在Java中聲明一個無參構造函數的目的是什么?


我們在定義一個類的時候,如果需要重新寫一個構造函數,就必須要寫一個無參構造函數,如下代碼所示,那這到底是為什么?

public class Fruit {
 
    private String name;
 
    // 必須顯式聲明一個無參構造函數
    public Fruit(){}
 
    public Fruit(String name){
        this.name = name;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
}

  

要回答這個問題,我們就來把這個無參構造函數去掉試試。

按照如下方式,用起來也沒多大的問題:

    public static void main(String[] args){
        Fruit apple = new Fruit("apple");
        // print "apple"
        System.out.println(apple.getName());
    }

  但是,當我們需要派生一個子類的時候,編譯就報錯了:

public class Apple extends Fruit {
    // There is no default constructor available in 'cn.zx.demo.Fruit'
}

  

這是因為,子類在使用自己的默認無參構造函數初始化的時候,會執行super()來調用父類的默認無參構造函數,但是父類中此時沒有這樣的構造函數,因此編譯器認為出現了異常。

如果我們在父類Fruit中顯式地聲明一個無參構造函數,就像本文一開始演示的代碼一樣,那么就不會出現這樣的問題了。

再進一步思考,如果子類實例化的時候不使用super()來調用父類的無參構造函數是不是就不會出現這樣的問題了呢?

答案是肯定的:

public class Apple extends Fruit {
 
    public Apple(String name){
        super(name);
    }
 
}

  

只要在子類中指定調用父類中存在的構造函數,那么子類就是可以被正確初始化的,程序編譯也就沒有問題。

然而,我們其實並不能確定將要如何初始化一個子類,而且,我們也不可能為每一個子類都顯式地調用其存在的父類構造函數,這樣太過繁瑣。

比如,我們需要創建一個沒有name屬性的banana對象,那么此時將沒有合適的父類的構造方法供調用:

public class Banana extends Fruit {
 
    public Banana (){
        // 沒有合適的父類構造函數供調用
    }
 
}

  所以,為了可擴展,在類中重新寫構造函數的時候,額外聲明一個無參構造函數是一個良好的編程習慣。

 

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

以上都是轉載,內容也很好理解,但是今天看業務代碼,無參構造函數是私有的,private修飾的。這就很令人費解了,查了一下,應該是基於以下原因:

Java中如果將一個方法聲明為私有的,即通過private關鍵字來修飾,此時也就意味着該方法只能由這個類本身來調用。構造方法,類似於常規的方法,同樣可以被public、protected、private這三個關鍵詞修飾,但是構造方法不能有返回值。我們人為地將構造方法聲明為private,這樣其他的類就不能直接調用該類生成新的對象,也就避免了同一個類被反復創建的情況,這種情況,該類只有一個對象實例。

這種思想也就是單例模式的設計思想。在該種思想模式下,一個類只能是對應於一個對象,沒有其他的類可以創建新的對象,這也就保證了單例模式下只有一個對象。私有構造方法已經廣泛應用於jdk當中。


免責聲明!

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



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