class A {
public void fun(double d) {
System.out.println("A");
}
}
class B {
public void fun(int i) {
System.out.println("B");
}
}
class C extends A {
public void fun(int i) {
System.out.println("C");
}
}
class D extends B {
public void fun(double d) {
System.out.println("D");
}
}
class E extends B {
public void fun(double d) {
System.out.println("E");
}
public void fun(int i) {
System.out.println("F");
}
}
public class Test {
public static void main(String[] args) {
C c = new C(); c.fun(6); //line 1
D d = new D(); d.fun(6); //line 2
A x = new C(); x.fun(6); //line 3
B y = new D(); y.fun(6); //line 4
B z = new E(); z.fun(6); //line 5
}
}
此代码的输出为: C 乙 一种 乙 F
不确定行3的输出为何不是“ C”而是“ A”。因为动态绑定正在发生,所以不应该调用类中的方法吗?
对于第5行中的代码,将进行动态绑定,并且输出为“ F”而不是“ B”,但对于第3行则不会发生同样的事情。
答案 0 :(得分:6)
动态绑定适用于具有相同签名的方法。
当您为编译时间类型为x
的变量A
调用方法时,编译器只能考虑类A
(或其超类)中定义的方法(方法重载解析在编译时发生)。这意味着仅考虑public void fun(double d)
。
由于C
的{{1}}具有不同的签名,因此它不会覆盖public void fun(int i)
的方法,因此即使运行时类型为{变量A
是x
。
第5行中的行为不同。这里C
的编译时间类型是z
,类B
具有B
方法。由于public void fun(int i)
的运行时类型为z
,并且E
也具有签名为E
的方法,因此public void fun(int i)
的方法将覆盖E
的方法,因此将执行B
的方法。