1. 程式人生 > >子父類中的構造函數

子父類中的構造函數

pan super() 類實例化 不執行 jvm 實現 必須 bject 讀取

首先了解構造函數

構造方法的主要作用是完成對象的初始化工作,它能夠把定義對象時的參數傳給對象的域。即為對象成員變量賦初始值。

構造函數與類名相同,可重載多個不同的構造函數。如果在定義類時沒有定義構造方法,則編譯系統會自動插入一個無參數的默認構造方法,這個構造方法不執行任何代碼。

構造函數的調用

(1)子類只調用父類的默認(缺省)構造函數,即無形參構造函數。如果父類沒有默認構造函數,那子類不能從父類調用默認構造函數。 (2)子類從父類處調用父類默認構造函數,不能成為子類的默認構造函數。 (3)在創建對象時,先調用父類默認構造函數對對象進行初始化,然後調用子類自身自己定義的構造函數。 (4)如果子類想調用父類的非默認構造函數,則必須使用super來實現。 (5)子類必須調用父類的構造函數。可以通過系統自動調用父類的默認構造函數,如果父類沒有默認構造函數時,子類構造函數必須通過super調用父類的構造函數。 java 構造函數的執行過程 類初始化時構造函數調用順序: (1)初始化對象的存儲空間為零或null值; (2)調用父類構造函數; (3)按順序分別調用類成員變量和實例成員變量的初始化表達式; class Dollar { Money m = new Money(); Rmb r = new Rmb(); public Dollar() { System.out.println("Dollar is constructor."); } public static void main(String[] args) { new Dollar(); } } class Money { public Money() { System.out.println("Money is constructor."); } } class Rmb { public Rmb() { System.out.println("RMB is constructor."); } } 輸出結果: Money is constructor. RMB is constructor. Dollar is constructor.

子父類中的構造函數的特點:

  在子類構造對象時,發現,訪問子類構造函數時,父類也運行了。

為什麽會這樣呢?

  原因是:在子類的構造函數中第一行有一個默認的隱式語句。super();

子類的實例化過程:子類中所有的構造函數默認都會訪問父類中的空參數的構造函數。

為什麽子類實例化的時候要訪問父類的構造函數呢?

  那是因為子類繼承了父類,獲取了父類中的內容(屬性),所以在使用父類內容之前,首先要看父類如何對自己的內容進行初始化的。

  所以子類在構造對象時,必須訪問父類中的構造函數。為了完成這個必須的動作就在子類的構造函數中加入了super語句。如果父類中沒有定義空參數構造函數,那麽子類的構造函數必須用super明確要調用哪個構造函數(通過super的參數)。

註意:super語句必須要定義在子類構造函數的第一行,因為父類的初始化動作必須要先完成。

通過super關鍵字初始化父類內容時,子類的成員變量並未顯示初始化。等supe()父類初始化完畢後,才進行子類的成員變量顯示初始化。

一個對象的實例化過程:

  Person p = new Person ();

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

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

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

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

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

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

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

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

子父類中的構造函數