4

我想知道为什么这一点 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) );  
    }
}

我在一个测试问题中遇到了这个问题,但无法理解其背后的逻辑。

4

2 回答 2

8

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

ab.f(b)

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

因此,编译器决定调用带有签名的方法f(A a)

现在在执行时,VM根据方法调用目标的执行时类型(B.

Boverrides f(A a),以便调用覆盖实现 - 并返回 2。

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

于 2013-05-01T20:23:54.557 回答
0

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

int f(A a) {
  return 1;
}

b 属于 A 类,所以它是有效的。B 覆盖了 int f(A a),所以使用了这个方法。

int f(A a) {
    return 2;
}

希望有帮助。

于 2013-05-01T20:43:12.747 回答