Java覆盖混乱
我是java新手,现在我有一个关于方法重写的问题:Java覆盖混乱,java,Java,我是java新手,现在我有一个关于方法重写的问题: public class maintest { public static void main(String[] args) { new Zi(); } } public class Fu { public Fu() { show(); } public void show() { System.out.println("This is from Fu
public class maintest {
public static void main(String[] args) {
new Zi();
}
}
public class Fu {
public Fu() {
show();
}
public void show() {
System.out.println("This is from Fu show");
}
}
public class Zi extends Fu {
public Zi() {
show();
super.show();
}
public void show() {
System.out.println("This is from zi show");
}
}
运行此程序时,输出为:
This is from zi show
This is from zi show
This is from Fu show
有谁能给我一些简单易懂的解释,为什么第一条输出线是
This is from zi show
而不是
This is from Fu show
换句话说,为什么超类中的show方法是隐藏的?在构造函数中,您可以这样做
public Zi() {
super(); // <-- you didn't have this, so the compiler added it.
// your Fu class then calls Zi's show.
// Why? Because Zi has a method named show that override Fu's
// show method. So the Fu constructor (when it calls show()) gets the
// show implementation in Zi.
show(); // <-- first explicit show call (but the second "This is from zi show")
super.show(); // <-- then call the Fu.show()
}
public-Zi(){
Suffer(;)//超级类<代码>傅< /C>构造函数调用已经在子类中已被覆盖的方法<代码>显示,因此调用了重写方法。
让我们考虑输出的每一行。< /P>
第一行来自
Fu
的构造函数中对show()
的第一次调用,在调用Zi
的构造函数之前隐式调用
第二行来自Zi
的构造函数中的show()
第三行来自super.show()
,它显式地调用父类Fu
上的show()
方法。当您在Fu构造函数中调用show
时,将调用实际对象的show方法
基本上在内存中只有一个对象是Fu和Zi。这个对象的show方法是最深的(在继承树中)重写版本,在本例中是Zi的show。您已经通过Zi.show重写了Fu.show。这意味着即使在父类中调用show(),子类方法也会被调用
在一个真实的例子中
你的父亲(父母)有一家公司。你(孩子)从他那里继承了这家公司。你任命了一名新的接待员(用孩子替代父母的接待员)。现在,所有打到父亲公司的电话都会被你的接待员接到
希望这是清楚的。当调用new Zi()
时
它调用其构造函数
Zi() {
a. super(); //the Java compiler automatically inserts a call to the no- argument constructor of the superclass
b. show();
c.super.show();
}
a.当调用super()
类构造函数时。它查找show()
方法..(由于对象引用来自Zi类,所以Zi的show()
返回“这是来自Zi show”)
b.show()
-将返回“这是来自zi show”
c.super.show()
-将返回super的show()
您可以检查程序的流程。检查系统的输出。err.println()
方法
public class maintest {
static int i = 0;
public static void main(String[] args) {
new Zi();
}
}
class Fu {
public Fu() {
System.err.println("Fu Constructor " + maintest.i++);
show();
}
public void show() {
System.err.println("Fu show " + maintest.i++);
System.out.println("This is from Fu show");
}
}
class Zi extends Fu {
public Zi() {
System.err.println("Zi Constructor " + maintest.i++);
show();
super.show();
}
public void show() {
System.err.println("Zi show " + maintest.i++);
System.out.println("This is from zi show");
}
}
输出将是:
This is from zi show
This is from zi show
This is from Fu show
Fu Constructor 0
Zi show 1
Zi Constructor 2
Zi show 3
Fu show 4
System.out.println()和System.err.println()的输出顺序可能会有所不同
上面的输出告诉我们,首先创建Fu
类的对象(作为Zi
class扩展Fu
),然后调用Zi
类的show()方法和constructor
,因为super.show()
调用Fu
类的方法。这是您的输出。您在Zi
中重写了该方法,因此调用show()
的Zi
对象将始终调用Zi
版本。@dlev我不太明白,当super()时被调用,为什么它在Zi的上下文中运行?您能从内存位置的角度显示它吗?(比如JVM结构)如果您的Fu构造函数中没有显示,您应该看到您期望的结果。这个问题已经被问了十几次或更多次。您应该在发布新问题之前尝试搜索这个问题。@leigero感谢您的提示。我只是不知道应该搜索哪个关键字,因为我对java非常陌生。为什么在super()中使用关键字“This”参考Zi?不是关键字“this”…但是有一个对super()构造函数的隐式调用-我添加了它(super()).@Kuan这就是Java的工作方式。在任何构造函数中,Java在一开始都会隐式调用超类构造函数。应答者向您展示了它的显式外观,因此您可以看到为什么您的输出有三行,而不是您可能期望的两行。@Kuan“this”指类Zi的对象。@Adtya谢谢你的解释,但是如果我想在super()中使用Fu的show呢?我怎么做?为什么是第一个show()呢是在Zi而不是Fu的上下文中吗?如果Fu的show中的第一个show,为什么这指的是Zi?当在子类中重写一个方法,并且我们正在构造该子类的实例时,对该方法的所有调用都将转到该子类的方法,除非显式重写(例如使用super
)在上面的例子中,它不是关于“上下文”,而是关于正在构造的对象的类型。这里我们正在构造一个类型为Zi
的对象,因此即使Fu
的构造函数调用show()
,它仍在调用Zi
的show
。感谢您的解释,但是如果我想在super()中使用傅的show呢?我该怎么做?谢谢你的解释,我想我可能需要读更多的书才能理解这一点。你能给我一些关于该方法如何在Fu和Zi中显示并存储在memory中的细节吗?谢谢你的解释,但是如果我想在super()中使用Fu的show呢?我该怎么做?你不能。但是如果调用super.show(),在子类方法中
然后会调用super方法,这是否意味着:好的模式永远不会覆盖在超类构造函数中的方法之上?谢谢解释,但是如果我想在super()中使用Fu的show呢?我该怎么做?因为对象引用是super()中Zi的对象,所以它将始终调用Zi的show()方法来显示Fu的show()方法,您必须显式定义对象对Fu类型的类型引用。这样它将调用..@sakura,是的,我需要,很抱歉没有格式化..:(
This is from zi show
This is from zi show
This is from Fu show
Fu Constructor 0
Zi show 1
Zi Constructor 2
Zi show 3
Fu show 4