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
}
}
Run Code Online (Sandbox Code Playgroud)
该代码的输出是:C B A B F
不知道为什么第3行的输出不是“ C”,而是“ A”。因为动态绑定正在发生,所以不应该调用类中的方法吗?
对于第5行中的代码,将进行动态绑定,并且输出为“ F”而不是“ B”,但对于第3行则不会发生相同的情况。
动态绑定适用于具有相同签名的方法。
当您为variable调用一个方法x,其编译时间类型为时A,A编译器只能考虑在类(或其超类)中定义的方法(方法重载解析在编译时进行)。这意味着仅public void fun(double d)考虑。
由于C的public void fun(int i)具有不同的签名,它不覆盖A的方法,因此它不能被执行,即使该变量的运行时类型x是C。
在第5行中,行为不同。此处的编译时类型z为B,而类B具有一个public void fun(int i)方法。由于运行时类型z是E,并且E也具有与签名的方法public void fun(int i),E的方法覆盖B的方法,因此E被执行的方法。