Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/402.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java覆盖混乱_Java - Fatal编程技术网

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

我是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 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