Rez*_*eza 5 java methods overriding overloading
当我遇到一些奇怪的东西时,我正在测试代码,我无法弄清楚为什么会发生这种情况.所以我将举一个关于那里发生的事情的简单例子.
考虑这些课程
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");
}
}
Run Code Online (Sandbox Code Playgroud)
现在在我的main方法中我有这种实例化:
B b = new E();
C c = new E();
E e = new E();
Run Code Online (Sandbox Code Playgroud)
我调用这些方法并获得以下输出.
b.print(b);
c.print(e);
Run Code Online (Sandbox Code Playgroud)
OUTPUT:
C
C
Run Code Online (Sandbox Code Playgroud)
我有两个解释,但每个解释都与这些方法调用之一相矛盾.也有可能我的两个解释都是完全错误的,所以我在这里没有任何要求.
解释1
b.print(b):b是的实例E,并upcasted到B.B有一个print方法,它接受类型的参数A但它被类重载E.但是,此方法的参数b是up upted B,因此方法调用匹配C.print(A a)(因为C是超类E)的签名,因此结果是合理的.
c.print(e):以同样的方式思考,不会在这里解释输出.c是一个实例E并且被提升为C.C有一个print方法,它接受类型的参数A但它被类重载E.但与上述情况相反,此方法的参数e与签名相匹配E.print(E e).所以通过这个推理,输出应该是E而不是!
解释2
在这里,我从第二个方法调用和原因开始.
c.print(e):c是的实例E,并upcasted到C.C有一个print接受类型参数的方法A.这个方法的参数e是一个实例,E而其实例又是它的子类A.因为它已被上传E.print(E e)隐藏起来c.因此,方法调用匹配签名,C.print(A a)并且该逻辑输出是合理的.
b.print(b):b是的实例E,并upcasted到B.B有一个print方法,接受类型的参数A(再次隐藏).因此,方法调用匹配签名,A.print(A a)并且通过该逻辑,输出应该是A,而不是.
我真的很困惑这里发生了什么.请有人解释一下.
将调用哪种方法分两步:
在运行时,根据实际实例类型(多态)确定将使用哪些重写方法
b.print(b); // B b = new E();
在编译时,由于声明的类型b是B,只能使用print接受B(或其超类(A)的实例),这意味着:A.print(A a)
在运行时,一旦重载方法已在先前步骤中选择,实际类型b(E)用于选择的版本print(A a)将用于:C.print(A a)在A.print(A a)
c.print(e); // C c = new E(); E e = new E();
在编译时,声明的类型c是C和声明的类型e是E这样的,因此只能使用这些方法:A.print(A a)和C.print(A a)
因此,在运行时,实际的类型e是E更具体的(在类层次结构中意味着更高)版本被选中:C.print(A a)
| 归档时间: |
|
| 查看次数: |
1203 次 |
| 最近记录: |