java中的繼承

子父類構造函數-子類的演化過程


先看下邊的程序運行的結果是什麼

這段程序 的運行結果是

zi show....1...0
zi show....2....10
zi show....1...10

原因是,看下圖內存分析 圖

原因:

這裏是程序 剛開始 執行的地方

Zi zi = new Zi();

  程序 會先執行子類的構造函數 ,在子類的構造方法中,有一句super()語句,當代碼執行到這一句後,程序 會進入Fu類中運行,


這裏,由於父類 的構造方法中,也有一句super(),它默認繼承Object類,不做考慮,當它運行到Show()方法時,由於子類重寫了父類的show()方法,所以這時程序 會調用子類的show()方法,由於子類對象這會在堆中並沒有進行賦值操作 ,所以這時的num = 0; (注意這裏的num會是默認值 0),所以它會先運行子類的show()方法,並且num = 0;

然後父類 的構造方法中,會繼續執行return語句,父類 彈棧,然後子類的構造方法中,super(),調用完後,這裏子類中的num變量會被賦值爲10,最後

Zi zi = new Zi();
這一句代碼執行完畢 ,

zi.show();
再執行這一句代碼,num = 10;


一個對象實例化過程

Person p = new Person();

1,JVM會讀取指定的路徑下的Person.class文件,並加載 進內存,並會先加載Person的父類 (如果有直接的父類 的情況下)

2,在堆內存中開闢空間,分配 地址,

3,並在對象空間中,對對象中的屬性進行默認初始化。

4,調用對應的構造函數進行初始化

5,在構造函數 中,第一行會先到調用父類 中構造函數 進行初始化,

6,父類 初始化完畢 後,在對子類的屬性進行顯示 初始化。

7,在進行子類構造函數的特定初始化

8,初始化完畢 後,將地址值 賦值給引用變量


下面的例子加上了構造代碼塊

class Fu{
    {
        System.out.println("fu contructor  ...");--->  1,第一步
        show();   ---------------------------------->子類重寫父類方法,運行子類的方法
    }
    Fu(){
        super();//Object        
         //顯示初始化
        //構造代碼塊初始化
        System.out.println("fu run");-----------------> 3.第三步             
    }
    public void show(){
        System.out.println("fu show ...");
    }
}
class Zi extends Fu{
    int num = 9;
    {
        System.out.println("zi contructor  ..."+num);---->4.第四步
        num = 10;
    }
    Zi(){
        super();//注意:super調用完之後,中間是下邊這兩步
        //顯示初始化
        //構造代碼塊初始化
        System.out.println("zi run ..."+num); ------------>5.第五步
    }
    @Override
    public void show() {
        System.out.println("zi show ..."+num);-------------> 2.第二步
    }                                          -------------> 6.第六步
}
public class DemoSummary {
    public static void main(String[] args){
        new Zi().show();------------------------------------>程序入口
    }
}

運行結果是

fu contructor  ...
zi show ...0
fu run
zi contructor  ...9
zi run ...10
zi show ...10






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章