我试图翻转一个物体。但是在运行时,对象类仍然是派生类。
Derived drv = new Derived();
Base base = (Base) drv;
System.out.println("Class : " + base.getClass());
//prints -> Class : class packagename.Derived
那么为什么类属性没有改变?
答案 0 :(得分:14)
那么为什么类属性没有改变?
因为对象没有改变,只是你所拥有的引用类型。施放对物体本身没有任何影响。
在Java中,与其他语言(谢天谢地)不同,引用的类型在很大程度上不会影响您获得的方法版本。例如,考虑这两个类(由2rs2ts提供 - 谢谢!):
class Base {
public Base() {}
public void foo() {
System.out.println("I'm the base!");
}
}
class Child extends Base {
public Child() {}
public void foo() {
System.out.println("I'm the child!");
}
}
此代码:
Child x = new Child();
Base y = (Base) x;
y.foo();
...输出
I'm the child!
因为即使y
的类型为Base
,我们正在调用foo
的对象也是Child
,所以Child#foo
被调用。这里(再次由2rs2ts提供)是example on ideone可以使用的。
尽管经过Child#foo
引用我们获得Base
这一事实对多态性至关重要。
现在,您正在调用的方法(getClass
)只能 为Object#getClass
,因为它是final
方法(子类不能覆盖它)。但这个概念至关重要,我认为它可能是你所询问的核心。
引用类型的主要作用是确定允许访问的对象的哪些方面。例如,假设我们将bar
添加到Child
:
class Child extends Base {
public Child() {}
public void foo() {
System.out.println("I'm the child!");
}
public void bar() {
System.out.println("I'm Child#bar");
}
}
此代码无法编译:
Child x = new Child();
Base y = (Base) x;
y.bar(); // <=== Compilation error
...因为Base
没有bar
方法,因此我们无法通过类型为bar
的引用访问对象的Base
方法。
答案 1 :(得分:0)
您无法在Java中更改实例的类型。您对演员表所做的一切都是从不同类型的变量中引用它。
答案 2 :(得分:0)
向上转换不会更改对象的类型。事实上,NOTHING改变了Java对象的类型。
这是OO编程的核心:一个对象具有一定的行为,不会受到外界的影响。