Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中的强制转换_Java - Fatal编程技术网

Java中的强制转换

Java中的强制转换,java,Java,如果我有一个类A,它有一个方法foo(),还有一个类B,它从A扩展并覆盖foo()。如果我写A A=newb()

如果我有一个类
A
,它有一个方法
foo()
,还有一个类
B
,它从
A
扩展并覆盖
foo()
。如果我写
A A=newb()((A)A).foo()
-哪个
foo
将被激活?一方面,动态类型是
B
,并且
foo()
被很好地覆盖,另一方面-此强制转换是否使a成为
a
的动态类型?

否,实例将始终保持
B
。您使用new创建了
B
,并且强制转换它不会更改对象的实际实例。

请尝试并查看


(扰流板:B中的'foo'将覆盖'A'中的'foo',因此即使您执行
((A)A).foo()
您也将执行B中的'foo'。这在OO语言中很常见。

B.foo()
将被调用。如果
B
没有覆盖/实现方法,将调用
a.foo()
(如果定义了
a.foo()

考虑下面的代码。
通过将
b
强制转换为
A
可以将访问权限限制为仅在
A
中声明的公共成员(或其任何继承的公共成员),但在涉及公共方法的实现时,将忽略强制转换或变量的声明方式。重要的只是变量的实际数据类型(不是如何声明它,而是如何创建它)

与其将
b
转换为
A
,不如像这样创建
b
ab=newb()
。它的行为方式与您将其声明为
B
时相同,但将其转换为
A

当涉及到调用方法时,对象的声明和/或强制转换只提供“接口”(即使声明/强制转换的类型是类,也可以将其视为只包含相应类声明或继承的公共方法的接口)。这些方法的实现是由实际数据类型提供的

public class Temp {
    public static void main(String[] args) {
        B b = new B();
        ((A) b).foo(); // real type is B
        b.fooA();// real type is B, but B doesn't override fooA() so the implementation is inherited from A
        // ((A) b).fooB(); error: `A` doesn't know about fooB
        b.fooB();
        C c = new C();
        c.foo(); // real type is C, but C doesn't override foo() so the implementation is inherited from B
        A b1 = new B();
        b1.foo(); // real type is B
        A a = new A();
        a.foo(); // real type is A
    }
}
class A {
    public void foo() {
        System.out.println("A");
    }
    public void fooA() {
        System.out.println("fooA");
    }
}
class B extends A {
    @Override
    public void foo() {
        System.out.println("B");
    }
    public void fooB() {
        System.out.println("fooB");
    }
}
class C extends B {
}
产出:

B
B
fooA
fooA
fooB
B
B
A

为什么不编写一些非常简单的代码,自己看看呢?simple不能解释这种强制转换在这种情况下的真正含义。dynamic恰恰意味着a将是B的实例。为了证明,创建一个C类,它像B一样扩展a,并在运行时随机选择a=new B或new C。这是非常动态的!显式地将a转换为a不会在方法调用时执行任何操作。通常,当您不关心实现和/或您可能希望支持其他不同的实现者时,您会保留父对象类型中的子类(或接口)。把一个B对象放在一个a中,你只是把自己局限于a的方法。那么它到底做了什么呢?我从来没有真正明白过。@Nir对于你刚才在评论中提出的这个问题,最简单的答案并不是最好的答案。最好的答案是你翻出你的书,学习多态性的基础知识,然后你就可以自己回答这个问题了。例如,B有一个函数
notInA()
,而你有一个对象
a=new B()
然后必须强制转换到B:
((B)a).notInA()
才能访问此函数。但是San Jacinto是对的,阅读多态性,什么都没有。在java中,向上转换是不可操作的。编辑:我说谎。它所起作用的一个地方是现场访问。如果A和B都声明了一个字段x,那么((A)obj).x和((B)obj).x不引用同一个位对象。我认为将值强制转换为A没有意义,因为在Java中方法总是虚拟的。对于C语言或C++语言来说,这并不常见。