2016-02-08 44 views

回答

6

你這樣做是爲了防止其他人訪問您的實現類獲取有關接口的詳細信息。例如,你可以隱藏你的實現類型庫中,給類型包訪問,並返回你的接口的實例到庫的用戶:

// This is what the users of your library know about the class 
// that does the work: 
public interface SomeInterface { 
    void doSomethingUseful(); 
    void doSomethingElse(); 
} 

// This is the class itself, which is hidden from your clients 
class MyImplementation implements SomeInterface { 
    private SomeDependency dependency = new SomeDependency(); 
    public void doSomethingUseful() { 
     ... 
    } 
    public void doSomethingElse() { 
     ... 
    } 
} 

您的客戶獲取的對象是這樣的:

public class MyFactory { 
    static SomeInterface make() { 
     // MyFactory can see MyImplementation 
     return new MyImplementation(); 
    } 
} 

這個技巧在實現使用大量庫時變得有用。您可以高效地將庫的接口與其實現進行分離,以便用戶不必知道庫的內部依賴關係。

+3

我沒有看到向用戶提交一個接口與向用戶提供實現類之間的區別。 「外觀和感覺」是一樣的... – Nitek

+1

@Nitek:這裏有一個例子解決了這個問題,OP希望公開的方法暴露給最終用戶不想公開的測試:http:/ /stackoverflow.com/a/6913509/217324 –

+0

@Nitek這不是關於外觀和感覺,而是關於將你圖書館的用戶與他們不應該看到的東西隔離。 – dasblinkenlight

-3

接口可以由多個類來實現。沒有規定只有一個類可以實現這些。接口提供了對java的抽象。

http://www.tutorialspoint.com/java/java_interfaces.htm 你可以從這個鏈接

+3

這是一個「鏈接 - 僅回答「,這被認爲是StackOverflow上的錯誤形式,因爲鏈接不好。問問自己,如果沒有鏈接,答案會是多麼的好。除非你準備好讓自己的答案足夠獨立,否則它應該是一個評論。 –

+0

我不認爲提問者認爲你在一個實現類中是有限的。我認爲他們更想知道爲什麼有人會在只有一個實現類的情況下拆分接口。 –

0

其中一個原因是保持開放/關閉原則,其中規定您的代碼應該打開以進行擴展,但關閉以進行修改。儘管你現在只有一個實現類,但是隨着時間的推移,你將需要另一個不同的實現類。如果事先將實現提取到接口中,則只需編寫另一個實現類即。您無需修改​​完善的代碼,消除了引入錯誤的風險。

0

它可以讓您靈活地在將來添加更多實現,而無需更改引用該接口的客戶端代碼。

另一個有用的例子是在需要時模擬Java中的多重繼承。例如,假設你有一個接口MyInterface和實施:

public interface MyInterface { 
    void aMethod1(); 
    void aMethod2(); 
} 

class MyInterfaceImpl implements MyInterface { 
    public void aMethod1() {...} 
    public void aMethod2() {...} 
} 

你也有一個不相關的類有自己的層次:

public class SomeClass extends SomeOtherClass { 
... 
} 

現在你想SomeClassMyInterface類型,但你還想繼承MyInterfaceImpl中已有的所有代碼。既然你不能既延長和SomeOtherClassMyInterfaceImpl,可以實現接口和使用委託:

public class SomeClass extends SomeOtherClass implements MyInterface { 
    private MyInterface myInterface = new MyInterfaceImpl(); 

    public void aMethod1() { 
    myInterface.aMethod1(); 
    } 

    public void aMethod2() { 
    myInterface.aMethod2(); 
    } 
    ... 
} 
0

要尊重接口分離原則。

創建接口的決定不應該基於實現類的數量,而應該基於對象使用的不同方式的數量。對象使用的每種方式都由一個接口來表示,該接口由使用它的代碼定義。假設你的對象需要存儲在內存中,保存對象的集合中。同一個對象也需要存儲在某個持久性存儲中。

說你先實現持久性。存儲系統需要的是持久對象的唯一標識符。使用getUniqueId方法創建一個接口,稱爲Storable。然後您實現存儲。

然後,您執行該集合。您可以使用方法compareTo定義接口中存儲的對象所需的內容,如Comparable。然後您可以依賴於Comparable實現該集合。

要定義的類將實現兩個接口。

如果您正在定義的類實現單個接口,那麼該接口將不得不代表收集和存儲系統的需求。這會導致,例如:

  • 集合的單元測試必須寫入實現Storable的對象,增加複雜度級別。如果稍後需要顯示對象時,您將不得不將顯示代碼所需的方法添加到單個接口,並修改測試的收集和存儲以實現顯示所需的方法。

我在此討論對測試代碼的影響。如果其他生產級別的對象需要存儲並且不顯示,問題會更大。項目規模越大,不尊重界面隔離原則所產生的問題就越大。

相關問題