尝试理解Java中的upcasting。最近观察到的奇怪行为。
示例:
public class A extends B {
public int i = 2;
public void printI() {
System.out.println("print i = " + this.i);
}
public static void main(String[] args) {
B a = new A(); // <- upcasting here
System.out.println("i = " + a.i);
a.printI();
}
}
class B {
public int i = 1;
public void printI() {}
}
//Output:
//i = 1
//print i = 2
似乎,upcasted对象有两个独立的“i”属性。一个“i”直接访问(a.i),另一个通过子类(a.printI())的方法访问。
看起来upcasted对象从子类获取属性,从子类获取方法。
对象如何有两个单独的“i”?!
答案 0 :(得分:5)
似乎,upcasted对象有两个独立的“i”属性。
首先,值得明确术语。在A
和B
的每一个中都没有“upcasted object” - 而“i”是字段。
但是,这里有两个单独的字段。它不像一个字段“覆盖”另一个或类似的东西。
目前还不清楚尝试要实现的目标,但在i
阴影中A
的声明 {{1}的声明在i
中。有关详细信息,请参阅section 6.4 of the Java Language Specification。
请注意,在几乎所有情况下,字段都应该是私有的 - 此时隐藏真的无关紧要,因为您不会尝试引用未在您编码的类中声明的变量反正。
答案 1 :(得分:1)
这就是Java的工作方式。您有两个字段“可用”,它们恰好具有相同的名称。当你从子类引用时,它隐藏了超类的版本,但它仍然存在。