我很难理解为什么在标有“ //// 1”的行中,程序将返回62而不是34。 谁能一步一步解释?我是Java的入门者,正在努力理解执行顺序。
class X {
public void proc(X p){
System.out.println(12);
}
}
class Y extends X{
public void proc(X p){
System.out.println(62);
}
}
class Z extends Y{
public void proc(Z p){
System.out.println(34);
}
}
class Main4{
public static void main(String[] args){
X x = new Z();
Y y = new Z();
Z z = new Z();
x.proc(z);////1
}
}
任何帮助都会很棒!谢谢!
答案 0 :(得分:1)
template<int data_size> struct
在编译时从x.proc(z)
类型(即x
)的方法中选择。唯一可用的方法是X
。
还请记住,proc(X)
中的public void proc(Z p)
不会覆盖Z
。
答案 1 :(得分:1)
您之所以得到此结果,是因为您的proc
方法不会相互覆盖。
最简单的方法是添加一个@Override
注释:
static class Z extends Y {
public Z() {
v += 9;
}
@Override
public void proc(Z p) {
System.out.println(34);
}
}
这将无法编译并显示错误消息
Test.Z类型的proc(Test.Z)方法必须重写或实现超类型方法
每当您打算覆盖某个方法时,最好添加此批注-这样编译器可以检查您是否确实这样做了。
要解决该错误并覆盖该方法以获得所需的输出,可以将参数的类型更改为X
:
static class Z extends Y {
public Z() {
v += 9;
}
@Override
public void proc(X p) {
System.out.println(34);
}
}
现在,它再次编译,并产生34
。
您的示例中发生的事情是,您的类Z
而非重载方法是将void proc(Z p)
的重载方法void proc(X p)
添加到X
中的{em {1}}。重载解析基于编译时类型,因此只有X
中的方法可用并被选择。该方法在Y
中被覆盖,因此实际上是在运行时执行的。
因此,获得预期结果的另一种方法是保持X
,Y
和Z
不变,并将x
的引用类型更改为{{1 }}:
Z
此版本在public static void main(String[] args) {
Z x = new Z();
Y y = new Z();
Z z = new Z();
x.proc(z);//// 1
System.out.println(y.getV());
}
中调用 overloaded 方法,因为它是类型为Z
的参数的最具体的重载。