子父類構造函數-子類的演化過程
先看下邊的程序運行的結果是什麼
這段程序 的運行結果是
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