Java覆盖混乱

时间:2014-03-13 04:55:11

标签: 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 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方法?

7 个答案:

答案 0 :(得分:4)

在你的构造函数中,你这样做,

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()
}

答案 1 :(得分:1)

调用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”

  public Fu() {
           System.out.println(this.getClass().getName()); //add this.. it will return           **"Zi"**
           show(); // So this will return Zi's show(), due to refrence of Zi's object, when called by the sub class constructor.
   }

b。 show() - 将返回“这是来自zi show”

c。 super.show() - 将返回超级show()

答案 2 :(得分:0)

超类Fu构造函数调用已在子类中重写的方法show,因此已调用重写方法。

答案 3 :(得分:0)

让我们考虑输出的每一行。

第一行来自show()构造函数中第一次调用Fu,在Zi的构造函数调用之前隐式调用 }。

第二行来自show()的构造函数内的Zi

第三行来自super.show(),它明确调用父类show()上的Fu方法。

答案 4 :(得分:0)

当你在Fu构造函数中调用show时,现在可以调用现在是Zi的show方法。

基本上在内存中只有一个对象是Fu和Zi。这个对象的show方法是最深的(在继承树中)覆盖它的版本,在这种情况下是Zi的节目。

答案 5 :(得分:0)

你已经被Zi.show覆盖了Fu.show。这意味着即使在父类中调用show(),也会调用子类方法。

在一个真实的例子中,

你父亲(父母)有一家公司。你(孩子)从他那里继承了这个。您指定一名新的接待员(由孩子覆盖父母的接待员)。现在所有打电话给父亲的公司将由接待员收到。

希望这很清楚。

答案 6 :(得分:0)

您可以查看程序的流程。检查System.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类的对象(Ziextends Fu)然后show()方法和{{1因为调用constructor Zi类的super.show() show()方法而调用Fu类。这是你的输出。