Java片段输出未被理解,可能与多态性有关

时间:2013-05-01 20:20:33

标签: java polymorphism

我想知道为什么这一点Java会产生2,而不是3:

public class Test {
    private static class A {
        int f(A a) {
            return 1;
        }
    }
    private static class B extends A {
        int f(A a) {
            return 2;
        }
        int f(B b) {
            return 3;
        }
    }

    public static void main(String[] astrArgs) {
        A ab = new B();
        B b = new B();

        System.out.println( ab.f(b) );  
    }
}

我在一个测试问题中遇到过这个问题,并且无法理解它背后的逻辑。

2 个答案:

答案 0 :(得分:8)

ab编译时类型只是A。因此,当编译器看到这个表达式时:

ab.f(b)

... 考虑在A及其超类上声明的方法签名(在这种情况下只是Object)。

因此,编译器决定使用签名f(A a)调用该方法。

现在在执行时,VM根据方法调用目标的执行时类型选择执行该签名的实现,即{ {1}}。

B覆盖B,以便调用覆盖实现 - 并返回2.

基本上,在编译时确定重载,根据调用目标和参数的编译时类型计算出要调用的方法签名,并且覆盖在执行时确定,以根据目标对象的执行时类型计算出要执行的确切实现。

答案 1 :(得分:0)

在这种情况下,ab是A类型,但实例化为B.只知道方法

int f(A a) {
  return 1;
}

b是A类型,因此它是有效的。 B覆盖int f(A a),因此使用此方法。

int f(A a) {
    return 2;
}

希望有所帮助。