我正在为考试做练习,发现一个样本问题使我完全迷失了。
对于以下代码,找到输出是什么:
class Moe {
public void print(Moe p) {
System.out.println("Moe 1\n");
}
}
class Larry extends Moe {
public void print(Moe p) {
System.out.println("Larry 1\n");
}
public void print(Larry l) {
System.out.println("Larry 2\n");
}
}
class Curly extends Larry {
public void print(Moe p) {
System.out.println("Curly 1\n");
}
public void print(Larry l) {
System.out.println("Curly 2\n");
}
public void print(Curly b) {
System.out.println("Curly 3\n");
}
}
public class Overloading_Final_Exam {
public static void main (String [] args) {
Larry stooge1 = new Curly();
Moe stooge2 = new Larry();
Moe stooge3 = new Curly();
Curly stooge4 = new Curly();
Larry stooge5 = new Larry();
stooge1.print(new Moe());
((Curly)stooge1).print(new Larry());
((Larry)stooge2).print(new Moe());
stooge2.print(new Curly());
stooge3.print(new Curly());
stooge3.print(new Moe());
stooge3.print(new Larry());
((Curly)stooge3).print(new Larry());
((Curly)stooge3).print(new Curly());
stooge4.print(new Curly());
stooge4.print(new Moe());
stooge4.print(new Larry());
stooge5.print(new Curly());
stooge5.print(new Larry());
stooge5.print(new Moe());
}
}
我想到了我的想法,但是当我运行Java时,我得到了完全不同的东西:
卷曲1
卷曲2
拉里1
拉里1
卷曲1
卷曲1
卷曲1
卷曲2
卷曲3
卷曲3
卷曲1
卷曲2
拉里2
拉里2
拉里1
前几个还可以,但是我真的不明白。
有人对此问题有很好的解释吗?
谢谢
最佳答案
我将从画一幅画开始...
Moe - print(Moe)
|
Larry - print(Moe), print(Larry)
|
Curly - print(Moe), print(Larry), print(Curly)
然后,我将跟踪变量:
拉里-stooge1->卷曲
萌-stooge2->拉里
萌-stooge3->卷曲
卷曲-stooge4->卷曲
拉里-stooge5->拉里
stooge1.print(new Moe())
stooge1-> Curly,因此称为Curly.print(Moe)
((Curly)stooge1).print(new Larry());
stooge1-> Curly,因此称为Curly.print(new Larry())
((Larry)stooge2).print(new Moe());
stooge2-> Larry叫Larry.print(new Moe());
stooge2.print(new Curly());
好的,这有点棘手(对不起,我之前在这里停过一个)
stooge2被声明为Moe。因此,当编译器正在查看要调用的内容时,它将调用print(Moe)方法。然后在运行时,它知道stooge2是Larry,因此它调用Larry.print(Moe)方法。
等等...
让我知道,如果这样做对您没有帮助。
(更新以澄清下一个)
因此,一般规则是:
编译器查看变量类型,以确定要调用的方法。
运行时将查看变量所指向的实际类,以决定从何处获取方法。
所以当你有:
Moe stooge2 = new Larry();
stooge2.print(new Moe());
编译器说:
可以将Larry分配给stooge2吗? (是的,因为Larry是Moe的子类)
Moe是否具有print(Moe)方法? (是)
运行时说:
我应该在此对象上调用print(Moe)方法... stooge2
stooge2指向拉里。
我将在Larry类中调用print(Moe)方法。
完成所有这些工作后,请尝试摆脱一些方法,然后看看这会如何改变。