在超类A和子类B中,i的变量abc分别为10和20,并且有一个方法callme()在子类中被覆盖。
如果我做
A a = new B();
B b = B(new A());
那我写
a.callme() -> calls B's method
b.callme() -> calls A's method.
这是因为基于实际对象调用了方法。
如果我做
str = a.abc; // will print 10 , based upon ref var type A
str = b.abc; // will print 20 , based upon ref var type B
为什么会有这种差异?为什么方法和变量都不基于实际对象访问?
谢谢
最佳答案
请记住,实例变量永远不会被覆盖,它们是隐藏的。引用类型决定了将访问其实例变量。
在子类中,方法callme()
被覆盖。因此,根据动态方法分配机制,由对象的类型决定在运行时将调用哪种方法。这是因为,对象是在运行时创建的。
例如
class A {
int abc = 10;
public void callme() {
System.out.println("In class A");
}
}
class B extends A {
int abc = 20; // hidden, not overidden
public void callme() {
System.out.println("In class B");
}
public static void main(String [] args) {
A a = new A();
a.callme(); // calls A's callme() method.
B b = new B();
b.callme(); // calls B's callme() method.
}
}