我想知道为什么这一点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) );
}
}
我在一个测试问题中遇到过这个问题,并且无法理解它背后的逻辑。
答案 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;
}
希望有所帮助。