当我遇到奇怪的事情时,我正在测试代码,我无法弄清楚为什么会发生这种情况。所以我将举一个简单的例子来说明那里发生的事情。
考虑这些类
public class A {
public void print(A a) {
System.out.println("A");
}
}
public class B extends A {
public void print() {
System.out.println("B");
}
}
public class C extends B {
public void print(A a) {
System.out.println("C");
}
}
public class E extends C {
public void print(E e) {
System.out.println("E");
}
}
现在在我的主要方法中,我有这种实例化:
B b = new E();
C c = new E();
E e = new E();
我调用这些方法并获得以下输出。
b.print(b);
c.print(e);
输出:
C
C
我有两种解释,但每一种都与这些方法调用之一相矛盾。也有可能我的两个解释都是完全错误的,所以我在这里没有声称任何东西。
解释1
b.print(b)
:b
是 的一个实例,E
并且向上转换为B
.B
有一个print
接受类型参数的方法,A
但它被 class 重载E
。然而,该方法的参数b
是向上转换为 的B
,因此方法调用与C.print(A a)
(因为C
是 的超类E
)的签名匹配,因此结果是合理的。c.print(e)
: 和上面的思路一样,这里就不解释输出了。c
是 的一个实例E
并且向上转换为C
.C
有一个print
接受类型参数的方法,A
但它被 class 重载E
。但与上述情况相反,此方法的参数e
与E.print(E e)
. 因此,根据这种推理,输出应该是 E,但不是!
解释2
在这里,我从第二个方法调用和原因开始。
c.print(e)
:c
是 的一个实例,E
并且向上转换为C
.C
有一个print
接受类型参数的方法A
。这个方法的参数是e
which 是一个实例,E
而它又是 的子类A
。由于它已被向上转换,因此E.print(E e)
是隐藏的c
。因此,方法调用与签名相匹配,C.print(A a)
输出是合理的。b.print(b)
:b
是 的一个实例,E
并且向上转换为B
.B
有一个print
接受类型参数的方法A
(同样它是隐藏的)。因此,方法调用与签名匹配,A.print(A a)
并且通过此逻辑,输出应该是 A,但不是。
我真的很困惑这里发生了什么。有人可以解释一下。