在超类A和子类B中,我将变量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
为什么会有这种差异?为什么两个方法和变量都不能根据实际对象进行访问?
由于
答案 0 :(得分:2)
请记住,实例变量永远不会被覆盖,它们隐藏。它是决定将访问其实例变量的引用类型。
在子类中,方法callme()
被覆盖。因此,根据动态方法调度机制,它是决定在运行时调用哪个方法的对象类型。这是因为,对象是在运行时创建的。
E.g
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.
}
}
答案 1 :(得分:0)
方法有一个实现,而字段只存储值/对象。能够覆盖方法的实现是有意义的。但我认为不需要“覆盖”一个领域。为什么不直接从子类中删除声明并使用超类的字段?
另一方面,也可以隐藏方法。但你必须把它们变成私人的。
class OuterClass {
void test() {
InnerSubClass isc = new InnerSubClass();
isc.m(); // prints "In subclass"
((InnerSuperClass) isc).m(); // prints "In superclass"
}
class InnerSuperClass {
private void m() {
System.out.println("In superclass");
}
}
class InnerSubClass extends InnerSuperClass {
private void m() {
System.out.println("In subclass");
}
}
}