super 與 this 同時使用問題


大家都知道this 和 super 調用構造函數時都必須放在第一句,今天同學問我的一個問題有點意思。

那么:我怎么在子類中 顯式的用 super 初始化父類同時用 this 初始化子類?

-------------------------------------------------------------------------------------

首先大家必須認識到兩點:

1. super 調用構造函數的 作用是 為了初始化子類前先初始化父類,僅此而已。

2. 每個類的構造函數有且僅有一個會執行屬性的初始化,即使你用的this, 那最后實際上也是this 指向的那個構造函數會執行。

 

下面分兩種情況具體分析下

(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() 初始化父類,默認的或者帶參的。

 


免責聲明!

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



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