2010-10-17 99 views
39

假設我們有下面的代碼:類的私人構造延伸

class Test { 
    private Test() { 
     System.out.println("test"); 
    } 

} 

public class One extends Test { 

    One() { 
     System.out.println("One"); 
    } 

    public static void main(String args[]) { 

     new One(); 
    } 
} 

當我們創建一個對象One,即最初被稱爲父類的構造Test()。但由於Test()是私人的 - 我們得到一個錯誤。 一個很好的例子和擺脫這種情況的方式有多少?

回答

39

沒有出路。您必須創建一個可用的(protected,public或默認)超級構造函數,以便能夠擴展test

這種表示法通常用於實用程序類或單例中,您不希望用戶通過擴展它並實例化子類來創建自己的類實例,或者只需調用構造函數你的班。

如果您的class僅包含private構造函數,您還可以將class更改爲final,因爲它根本無法擴展。


另一解決方案是在具有其中test創建的test實例和從One每個方法調用委託給test實例的方法。這樣你就不必延長test

class Test { 
    private Test() { 
     System.out.println("test"); 
    } 
    public static Test getInstance(){ 
     return new Test(); 
    } 
    public void methodA(){ 
     //Some kind of implementation 
    } 
} 

public class One { 
    private final Test test; 
    One() { 
     System.out.println("One"); 
     test = Test.getInstance(); 
    } 

    public void methodA(){ 
     test.methodA(); 
    } 

    public static void main(String args[]) { 
     new One(); 
    } 
} 
+4

Test類的getInstance()方法應該是靜態的。否則,不可能像「Test.getInstance()」那樣進行調用。 – vanje 2010-10-17 11:37:12

+0

@vanje,謝謝,更新 – 2010-10-17 11:37:58

1

使testprivate構造或移動Onetest

順便說一句,你的示例代碼中包含的幾個問題:

  • 類應該被命名爲標題的情況下(的Test代替test
  • 我建議讓One的構造private,除非它是在同一個包裹中從不同類別呼叫
+0

如果你沒有測試的源代碼? – powder366 2017-01-13 14:33:23

0

其實,我發現有一條出路。像這樣:

class Base { 
private Base() { 

} 

public void fn() { 
    System.out.println("Base"); 
} 

public static class Child extends Base { 
    public void fn() { 
     System.out.println("Child"); 
    } 
} 

public static Base getChild() { 
    return new Child(); 
}} 

現在,您可以使用getChild()獲取擴展類的實例。

+5

這隻適用於放置靜態內部類時,因爲內部類可以訪問私有方法。不幸的是,這並沒有幫助,因爲如果你能夠改變這個類,你可以通過將構造函數設置爲受保護或公共位置來更好地服務。 – 2015-02-23 18:07:06