所以这道题是关于继承和方法重写的。 具体来说:子类具有与父类同名的方法,但签名不同的情况,例如:
class A has methodX(String arg)
class B extends A has methodX(int arg)
在正常情况下,将根据参数调用正确的方法。
但是在下面的代码中我遇到了一些我无法真正解释的奇怪行为:
static class A {
public void method1() {
System.out.println("m1.A");
}
public void method4(A arg) { //Original method4
System.out.println("m4.A");
}
}
static class B extends A {
public void method1() {
System.out.println("m1.B");
}
}
static class C extends B {
public void method4(A arg) { //Override method4 from Class A
System.out.println("m4.C");
}
}
static class E extends C {
public void method1() {
System.out.println("m1.E");
}
public void method4(E arg) { //NO OVERRIDE: Same name, but different method4 than in class A or C
System.out.println("m4.E");
}
}
public static void main(String[] args) {
A va = new A();
B vb = new B();
C vc = new C();
E ve = new E();
//At this point everything is fine
ve.method4(ve); //Calls method4 from class E based on parameter type - CORRECT
ve.method4(va); //Calls method4 from class C based on parameter type - CORRECT
//After this code strange things happen
vc = new E();
vb = vc;
vb.method1(); //Output: m1.E; method1 from class E is called - CORRECT
vb.method4(vb); //Output: m4.C; method4 from class C is called - why?
vc.method1(); //Output: m1.E; method1 from class E is called - CORRECT
vc.method4(vc); //Output: m4.C; method4 from class C is called - why?
vc.method4(ve); //Output: m4.C; method4 from class C is called - why?
}
所以上面程序的输出是:
m4.E
m4.C
m1.E
m4.C //why? Expected: m4.E
m1.E
m4.C //why? Expected: m4.E
m4.C //why? Expected: m4.E
行为
vb and vc
是我无法理解的。有什么想法吗?
最佳答案
我猜你期望 m4.E
被打印出来。但不要忘记,重载解析是在编译时执行的,而不是在执行时执行的。
C
和 B
都没有可用的 method4(E)
方法,因此编译器解析对 method4( A)
方法...不会被 E
覆盖。您在问题中对 m4.C//why?
的所有调用都是对具有签名 method4(A)
的方法的调用,在 E 的实例上调用
。现在 E
没有覆盖 method4(A)
,所以它保留在 C
中的实现,打印 m4.C
.
这里没有发生任何奇怪的事情。
关于java - 为什么调用错误的方法是: Strange inheritance behaviour,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26220799/