簡體   English   中英

為什么不能從構造函數是私有的類繼承?

[英]Why can you not inherit from a class whose constructor is private?

為什么 Java 不允許從構造函數是私有的類繼承?

Java 不會阻止使用私有構造函數對類進行子類化。

public class Main {
    static class A {
        private A() {
            System.out.println("Subclassed A in "+getClass().getName());
        }
    }

    static class B extends A {
        public B() {

        }
    }

    public static void main(String... ignored) {
        new B();
    }
}

印刷

Subclassed A in Main$B

它阻止的是無法訪問其超類的任何構造函數的子類。 這意味着私有構造函數不能在另一個類文件中使用,包本地構造函數不能在另一個包中使用。

在這種情況下,您唯一的選擇就是委派。 您需要調用工廠方法來創建“超級”類的實例並對其進行包裝。

因為一個類必須總是調用它的超類構造函數。 如果無法訪問超類構造函數,則無法初始化子類。

更多信息: JLS 8.8.10。 防止類的實例化


關於 Brian Roach 的評論:

[對父類構造函數] 的調用僅在您不顯式執行並且父類具有公共或受保護的無參數構造函數(或未定義任何在這種情況下存在默認無參數的情況下)時才是隱式的。 它是必需的,因為......這就是語言的工作方式。 孩子 [classes] 必須調用 [他們] 父母的構造函數。

請注意,當您在 Java 中實例化任何類時,總會隱式調用Object構造函數,因為它是所有類的超類。 它將執行其默認構造函數

public Object() {
}

來自 JLS 鏈接的注意事項:

如果隱式聲明了默認構造函數,但超類沒有可訪問的構造函數(第 6.6 節),該構造函數不接受任何參數且沒有 throws 子句,則會出現編譯時錯誤。

如果類的構造函數是私有的,則子類不能調用超級構造函數。 因此繼承將失敗。

如果您有子類,則子類(子類)構造函數有 2 種可能性: 1. 默認構造函數(無參數構造函數):在這種情況下,默認構造函數將自動嘗試調用父類構造函數:由於父類構造函數,這將失敗是私人的。 2. 參數化構造函數:當您嘗試為具有參數化構造函數的子類創建對象時,您需要通過傳遞參數或不傳遞參數來強制從子類構造函數調用父類構造函數:這也會失敗,因為父構造函數是私人的。

由於子類將具有默認構造函數或參數化構造函數,並且不可能擁有它們中的任何一個,因此您不能擁有具有私有構造函數的父類的子類。

是的,在 Luiggi 的回答中添加了一些東西,在創建單例類時使用了 Java 的這個特性,它只允許創建該類的一個實例。

這是因為,當我們進行繼承時,編譯器的工作是通過在每個類構造函數的第一條語句中編寫 super() 來使所有類與 Object 類建立直接或間接的關系。 當我們將構造函數設為私有時,這意味着不應從類外部訪問它,但是當我們進行繼承時,編譯器將隱式編寫這種類型的語句。

class SubClassName extends SuperClassName {
  public SubClassName() {
    super();  // which will indirectly going to call the Parent class constructor from outside its scope
  }
}

暫無
暫無

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

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