Java动态绑定
我正在准备考试,发现了一个让我完全迷失的示例问题。 对于下面的代码,找到输出是什么:
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时,我得到了完全不同的东西:
Curly 1 Curly 2 Larry 1 Larry 1 Curly 1 Curly 1 Curly 1 Curly 2 Curly 3 Curly 3 Curly 1 Curly 2 Larry 2 Larry 2 Larry 1
前几个是好的,但后来我真的不明白。 有人对这个问题有很好的解释吗?
谢谢
I am practicing for an exam, and found a sample problem that gets me totally lost.
For the following code, find what the output is:
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());
}
}
I had my ideas in mind, but then when I ran the java, I got something totally different:
Curly 1 Curly 2 Larry 1 Larry 1 Curly 1 Curly 1 Curly 1 Curly 2 Curly 3 Curly 3 Curly 1 Curly 2 Larry 2 Larry 2 Larry 1
The first few ones are OK, but then I really don't understand.
Anyone has a good explanation for this problem?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我会从画一幅画开始......
然后我会跟踪变量:
拉里 - stooge5 -> 拉里
stooge1.print(new Moe())
((Curly)stooge1).print(new Larry());
((Larry)stooge2).print(new Moe());
stooge2.print(new Curly());
好吧,这就是事情变得有点棘手的地方(抱歉我之前在这里停止了一个)
等等...
如果一直遵循这一点对您来说不成功,请告诉我。
(更新以澄清下一个)
所以一般规则是:
所以当你有:
编译器说:
运行时说:
一旦你完成了所有这些工作,尝试摆脱一些方法,看看这会如何改变事情。
I would start by drawing a picture...
Then I would keep track of the variables:
Larry - stooge5 -> Larry
stooge1.print(new Moe())
((Curly)stooge1).print(new Larry());
((Larry)stooge2).print(new Moe());
stooge2.print(new Curly());
Ok, this is where it gets a bit trickier (sorry I stopped one before here)
etc...
Let me know if following that all the way through doesn't work out for you.
(updated to clarify the next one)
So the general rule is:
So when you have:
the compiler says:
the runtime says:
Once you have worked all that out try getting rid of some of the methods and see how that changes things.
实际上,这个问题并不像看起来那么简单,因为Java既是静态绑定的,也是动态绑定的。 在了解从本练习中获得的所有结果之前,您必须先了解每种方法的应用场合。
TofuBeer提到的一般规则仅在动态绑定情况下才是正确的。 在静态绑定中,决策仅在编译时做出。
您的示例混合了动态绑定(当方法被重写时)和静态绑定(当方法被重载时)。
请查看此问题了解更多详细信息。
Actually, this problem is not as simple as it seems, since Java is both static and dynamically bound. You have to understand where each is applied before you will understand all the results you are getting from this exercise.
The General rule mentioned by TofuBeer is only correct in the dynamic binding case. In static binding, decisions are only made at compile time.
Your example mixes the dynamic binding (when methods are overridden) and static binding (when methods are overloaded).
Take a look at this question for more details.
提示是在查看对象时忽略左侧的值。 相反,在声明期间查看右侧的值,这是对象的实际值。
A hint is to disregard the value on the left when looking at objects. Instead, look at the value of the right during the declaration, this is the actual value of the object.