詳解Java構造方法為什么不能覆蓋,我的鑽牛角尖病又犯了....


看Think in Java,遇到個程序

class Egg2 {
    protected class Yolk {
        public Yolk() {
            System.out.println("Egg2.Yolk()");
        }

        public void f() {
            System.out.println("Egg2.Yolk.f()");
        }
    }

    private Yolk y = new Yolk();

    public Egg2() {
        System.out.println("New Egg2()");
    }

    public void insertYolk(Yolk yy) {
        y = yy;
    }

    public void g() {
        y.f();
    }
}

public class BigEgg2 extends Egg2 {
    public class Yolk extends Egg2.Yolk {
        public Yolk() {
            System.out.println("BigEgg2.Yolk()");
        }

        public void f() {
            System.out.println("BigEgg2.Yolk.f()");
        }
    }

    public BigEgg2() {
        insertYolk(new Yolk());
    }

    public static void main(String[] args) {
//        Egg2 e1 = null;
//        Egg2 e2 = new BigEgg2();
//        new Egg2();
          new BigEgg2();
//        e2.g();
    }
} ///:~

 

輸出

Egg2.Yolk()
New Egg2()
Egg2.Yolk()
BigEgg2.Yolk()

 

其實基本上我根據后面的幾個注釋,也大概明白了看的順序構造順序是什么,見圖

 

 構造順序圖

但是,看了輸出,我就納悶為什么,為什么第三行不是BigEgg2.Yolk(),不能覆蓋嗎?

Egg2.Yolk()
New Egg2()
Egg2.Yolk()
BigEgg2.Yolk()

 

分析一下

BigEgg2Egg2的子類,他們都有Yolk的內部類,而且BigEgg2.Yolk繼承了Egg2.Yolk。注意此處,同名類可以繼承。

那么,他們構造方法為什么不能覆蓋,都是Public Yolk(){}。

當然,網上都說子類繼承父類除構造方法以外的所有方法,但這是結果,我要知道為什么!!

 

先說幾個錯誤的觀點

1.

有說構造方法的方法名與類名必須一樣,父子類不能同名,故不能繼,所以不能覆蓋構造方法。

這個不用多說,這個例子,就是大神寫出來打這樣說的人的臉的。

 

2.

有說因為子類繼承父類的時候,先運行父類構造函數;具體的說就是運行父類時就會先“調用”父類的構造函數,注意“調用”和繼承不是一個含義,實質上是“自動運行”。

這個強行用中文語法來解釋的,達到中文6級了啊。

 

3.

有說構造方法不是成員函數,故不能繼承,所以談不上覆蓋。

這個真的有道理,是java官方文檔上的。大多數人找到這里估計就滿足了。

但是,跟太陽從東方升起西方落下那樣,我想知道為甚么這么設計啊啊啊啊啊啊!!!!!

 

4.

正確答案

(1).構造器代表這個類本身,在創建之時申請內存。

(2).子類創建的時候,會默認在構造方法的第一行調用父類的默認構造方法-,若修改了必須顯示調用。(這就是為什么創建子類時先創建完父類的原因了)

 

那么很明顯了,要是同名類之間可以覆蓋了,子類創建時就是創建了兩個自己而沒有父類。

Java設計的時候,他們絕對想到有些人會像強迫症那樣折騰個同名類繼承,然后實現構造覆蓋的場景吧....

 

總結

構造方法是唯一的,不能又造爸爸又造兒子


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM