请看一下这段代码:
class Foo {
public int a;
public Foo() {
a = 3;
}
public void addFive() {
a += 5;
}
public int getA() {
System.out.println("we are here in base class!");
return a;
}
}
public class Polymorphism extends Foo{
public int a;
public Poylmorphism() {
a = 5;
}
public void addFive() {
System.out.println("we are here !" + a);
a += 5;
}
public int getA() {
System.out.println("we are here in sub class!");
return a;
}
public static void main(String [] main) {
Foo f = new Polymorphism();
f.addFive();
System.out.println(f.getA());
System.out.println(f.a);
}
}
这里我们将类Polymorphism
的对象的引用分配给类型为Foo
的变量,即经典的polmorphism。现在我们调用已在类addFive
中重写的方法Polymorphism
。然后我们从getter方法中打印变量值,该方法也已在类Polymorphism中被覆盖。所以我们得到答案为10.但是当公共变量a
是SOP时,我们得到答案3 !!
这是怎么发生的?尽管引用变量类型是Foo但它指的是多态性类的对象。那么为什么访问f.a
不会导致类Polymorphism
中a的值被打印出来?请帮忙
答案 0 :(得分:5)
您正在隐藏a
的{{1}} - 实际上您应该收到编译器警告。因此,这是两个不同的Polymorphism
字段。与方法相比,字段不能是虚拟的。好的做法是根本没有公共领域,而只是改变私有状态(封装)的方法。
如果你想让它成为虚拟的,你需要把它作为一个带有访问器方法的属性(例如你所拥有的:a
)。
答案 1 :(得分:2)
这是因为您无法覆盖类变量。访问类变量时,引用的类型而不是对象的类型决定了你将得到什么。
如果删除子类中a的重新声明,那么我认为该行为将更符合预期。