簡體   English   中英

為什么私有基類構造函數導致“隱式超級構造函數不可見”

[英]Why does a private base class constructor result in “Implicit super constructor is not visible”

如果構造函數不在Java中繼承,為什么我會得到編譯錯誤(隱式超級構造函數A()對於默認構造函數是不可見的。必須定義一個顯式構造函數)?

class A {
    private A() {
    }
}

public class B extends A {

}

UPD。 我知道在隱式B構造函數中調用了super() 但我不明白為什么它不能使用super()訪問私有構造函數。 那么,如果我們只有私有構造函數,那么事實上的類是final嗎?

如果B extends A ,則B必須具有對A構造函數的訪問權。

請記住,構造函數總是調用super() 所以這里, B的隱式無參數構造函數不能調用A構造函數。

在Java中,如果創建Child Class的實例,則會隱式創建Parent Class實例。 所以Child Class構造函數應該對Child Class可見,因為它在第一個語句本身中使用super()調用Parent Class構造函數的構造函數。

因此,如果將Parent Class的構造函數更改為private ,則Child Class無法訪問它,也無法創建自己的任何實例,因此第一手編譯器根本不允許這樣做。

但是,如果你想private的默認的構造Parent Class ,那么你需要明確地創建一個重載的public在構造Parent Class &然后在Child class的構造函數,你需要使用調用super(param)的公共重載的構造Parent Class

而且,您可能會認為private構造函數的用途是什么。 當你不希望任何外部類中的其他人在你的類上調用new()時,主要使用private構造函數。 所以在這種情況下,我們提供了一些getter()方法來提供類的object 。在該方法中,您可以創建/使用類的現有Object並從該方法返回它。

例如。 Calendar cal = Calendar.getInstance(); 這實際上構成了Singleton設計模式的基礎。

重要的是要理解任何構造函數的第一行是調用超級構造函數。 如果您沒有自己調用超級構造函數,編譯器會通過在封面下插入super()來縮短代碼。

現在,如果你在超類私有中創建該構造函數,上面提到的概念將會失敗。

你的B類有一個默認的構造函數B() - 因為你沒有明確定義任何其他構造函數。 該構造函數隱式調用其超級構造函數A()。 但是你已經明確地將它作為A類的私有,所以你已經明確聲明沒有其他類,包括B,可以訪問它。

能行得通

class A {
    private A() {
    }
    public A(int i){
    }
}

public class B extends A {
    private A(){
        super(10);
    }
}

或者刪除私有A(),默認為public A(),除非你有另一個構造函數

class A {

}

public class B extends A {
    private A(){
        super();
    }
}

B的實例創建了類A的實例,因此如果A實現非默認約束,則B必須調用super(...) 所以構造函數應該受到protected因為B能夠調用super(...)

public class B extends A {

/*
* The default constructor B means
* public () B {super();}
*/
   public B() {
   }
}

因此,您應該定義一個可由B類訪問的構造函數

  1. 您可以更改父構造函數的訪問修飾符
  2. 或者您可以在父類中定義其他構造函數,該類可以由類B訪問並調用該構造函數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM