你們都知道this 和 super 調用構造函數時都必須放在第一句,今天同窗問個人一個問題有點意思。函數
那麼:我怎麼在子類中 顯式的用 super 初始化父類同時用 this 初始化子類?this
-------------------------------------------------------------------------------------spa
首先你們必須認識到兩點:code
1. super 調用構造函數的 做用是 爲了初始化子類前先初始化父類,僅此而已。blog
2. 每一個類的構造函數有且僅有一個會執行屬性的初始化,即便你用的this, 那最後實際上也是this 指向的那個構造函數會執行。編譯
下面分兩種狀況具體分析下class
(1) 父類提供了無參的構造函數構造函數
這種狀況比較簡單,由於子類的構造函數會自動的調用父類的無參構造方法,不須要顯式的加 super()。方法
但若是我手賤,硬要加怎麼辦?那麼會沒法編譯,否則這樣就屢次初始化父類了,有 致使不一致狀態 的潛在風險。總結
以下圖:父類提供了一個無參的構造函數,子類有一個默認構造函數,三個帶參的構造函數。
上文說了,實例化時,有且僅有一個構造函數會執行,當用son1(), son1(int p3) 都最終會調用最後一個構造函數,
因此最後一個構造函數執行前會調用父類的構造函數,若是son1(), son1(int p3) 也顯示的調用super(),則屢次初始化父類了,
這顯然是不對的;而 son1(int p2, int p3) 本身初始化屬性,因此沒這個問題,能夠顯式的調用super()。
public class father { int age; public father(){ age = 50; } } public class son1 extends father{ int property1; int property2; int property3; public son1(){ this(1,2,3); } public son1(int p3){ this(1,2,p3); } public son1(int p2, int p3){ super(); property1 = 1; this.property2 = p2; this.property3 = p3; } public son1(int p1, int p2, int p3){ super(); property1 = p1; property2 = p2; property3 = p3; } }
(2) 父類沒有提供無參的構造函數
此時必須在子類中顯式調用super(parm) 初始化父類。
一樣,後面的兩個構造函數必須顯式的調用 super
public class Father { int age; public Father(int age) { this.age = age; } } public class Son extends Father{ int property1; int property2; int property3; //構造函數1 public Son(){ //super(40); this(1,2,3); } //構造函數2 public Son(int p3){ //super(40); this(1,2,p3); } //構造函數3 public Son(int p2, int p3){ super(40); property1 = 1; this.property2 = p2; this.property3 = p3; } //構造函數4 public Son(int p1, int p2, int p3){ super(40); property1 = p1; property2 = p2; property3 = p3; } }
總結:this 與 super 調用構造函數時,都必須第一行,這樣致使他們不能同時使用,但你並不須要擔憂沒有初始化父類。
由於,this 最終指向的子類構造函數中,必定會調用super() 初始化父類,默認的或者帶參的。