为什么在第3行中没有进行动态绑定?

时间:2019-11-26 07:31:47

标签: java

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行则不会发生同样的事情。

1 个答案:

答案 0 :(得分:6)

动态绑定适用于具有相同签名的方法。

当您为编译时间类型为x的变量A调用方法时,编译器只能考虑类A(或其超类)中定义的方法(方法重载解析在编译时发生)。这意味着仅考虑public void fun(double d)

由于C的{​​{1}}具有不同的签名,因此它不会覆盖public void fun(int i)的方法,因此即使运行时类型为{变量Ax

第5行中的行为不同。这里C的编译时间类型是z,类B具有B方法。由于public void fun(int i)的运行时类型为z,并且E也具有签名为E的方法,因此public void fun(int i)的方法将覆盖E的方法,因此将执行B的方法。