2013-12-13 114 views
4

我正在閱讀有效的java教科書。第一項是關於使用靜態工廠方法而不是公共構造函數。我的疑問是,如果我指定Interface如何在Interface中指定靜態工廠方法?因爲java不支持interface中的靜態方法。該教科書規定了關於創建一個包含公共靜態工廠方法的不可實例化類的。但是這些方法如何訪問實現類的私有構造函數呢?接口類java中的靜態工廠方法

該教科書說,如果您要定義Interface Type,請創建一個不可實例化的類Types並在該類中包含靜態工廠方法。但是如何在Types類中定義的方法訪問具體實現的私有構造函數Interface Type

編輯: - 下面的句子是從課本引用的。請給我解釋一下其含義

「接口不能有靜態方法,所以按照慣例,靜態工廠方法(第4項)一份名爲類型被放在一個noninstantiable類的接口類型

編輯: - 從Effective Java By Joshua Bloch: Item1 - Static Factory Method

 public interface Foo{ //interface without plural 's' (question 1) 
    public void bar(); 
} 
public abstract class Foos(){ // abstract factory with plural 's' (question 1) 
    public static Foo createFoo(){ 
     return new MyFoo(); 
    } 
    private class MyFoo implements Foo{ // a non visible implementation (question 2) 
     public void bar(){} 
    } 
} 

我的問題採取的是如何能createFoo()調用的MyFoo

私有構造函數中的靜態方法
+0

這會幫助你理解: http://stackoverflow.com/questions/6129026/effective-java-by-joshua-bloch-item1-static-factory-method – user1933888

+0

它使這個概念更加清晰。但我的疑問依然存在。靜態方法createFoo()如何調用MyFoo的私有構造函數 –

回答

2

您可以將工廠定義爲返回接口,但在內部創建一個具體類。

例如:

public Interface I { } 

private class Impl implements I { 
} 

I buildI() { 
    return new Impl(); 
} 

訣竅是創建具有包專用的實現(或者即使它們是內部類私有)的構造中,然後只有工廠可以建立它們。

這種方法的強大之處在於,工廠可以根據需求構建適當的實施方案,並且所有這些都是在用戶看不見的情況下發生的。例如,當您使用工廠創建EnumSet時,有多種內部實現方式,具體取決於EnumEnumSet正在爲其構建的條目數量。對於Enums長字段使用少於64個條目的超快速版本,對於較長枚舉使用較慢版本。

要指定接口工廠所有你需要做的是:

public interface Factory { 
    I buildI(); 
} 

現在人們可以打電話給你setFactory(new FactoryImpl());那麼你可以調用factory.buildI()然後將自己的代碼返回的具體落實。

可以更進一步藉此和使用泛型:

public interface GenericFactory<T> { 
    T buildInstance(); 
} 

然後你setFactory變爲:

public void setFactory(GenericFactory<I> factory); 

要創建一個工廠,他們做的:

public class FactoryImpl implements GenericFactory<I> { 
    @override 
    I buildInstance() { 
     return new impl(); 
    } 
} 

但現在,您可以使用相同的工廠類來完成需要工廠的任何事情,只需更改t即可他是泛型的要求。

它可以調用私有構造函數的原因很簡單 - 它在同一個類中聲明!

在一個Java文件中,您可以使用私有構造函數創建類。然後在類中定義靜態方法,即使它是靜態的,仍然具有訪問構造函數所需的特權。

如果工廠和實現處於不同的類中,那麼它們將被放置在同一個包中,並且該方法將包私有而不是私有。

+0

我想迫使實現者添加靜態工廠方法,並在界面中指定一個預定義的名稱。 –

+0

buidI()方法應該是靜態的,以便用戶可以在不使用工廠對象的情況下調用該方法 –

+0

您的要求沒有任何意義。由於接口不需要靜態方法,因此也是不可能的。 –

0

它除了談到在執行創建通過靜態工廠方法的對象不是接口

public Interface MyInterface { 
    public void myFunction(); 
} 

public class MyClass implements MyInterface { 

    // constructor is made private 
    private MyClass() {} 

    // Use this to create object instead use static factory 
    public static MyClass getInstance() { 
     return new MyClass(); 
    } 

    public void myFunction(){ 
     // your implementation 
    } 
} 

以前的文章中也對靜態工廠方法會談.. What are static factory methods?

從書中我也找到了下面提到的鏈接很好讀 http://www.javacodegeeks.com/2013/01/static-factory-methods-vs-traditional-constructors.html

0

您不能在接口中定義工廠方法,但在接口中不能有構造函數:接口c annot被實例化。關鍵是在實現接口的類中使用工廠方法而不是構造函數,而不是在接口本身中。