2012-01-12 89 views
8

在我遇到的一個當前問題中(printing a file to a physical printer in Java)我一直在通過代碼運行,就像瘋子試圖從每個使用的類的javadoc中吞噬任何有用的遺漏信息。初始化接口?

現在,我從以前的問題中抽出了很多這樣的代碼,所以我沒有寫下自己。我注意到的問題是,我抓住的代碼正在初始化一個對象,比如說「SimpleDoc」,它實現了一個接口(Doc)並將其分配給該接口?!

小的代碼片斷:

Doc mydoc = new SimpleDoc(textStream, flavor, null); 

現在據我被帶到理解Java中,我們創建對象。我熟悉繼承,並且熟悉使用接口允許類「繼承」多個超類的技巧。

但這只是不正確。你可以創建一個實現接口的類,這對我來說很好。但是,當創建接口並將對象縮小到接口時發生了什麼?當我準確地引用mydoc時,我在訪問什麼?

+2

mydoc是實現「Doc」接口的對象的引用。在這種情況下,該接口用於標識可以通過mydoc引用變量調用的方法。請注意,變量(mydoc)仍然是對象的引用。 – DwB 2012-01-12 20:54:56

回答

5

訣竅是認識到你不是「創建」,「實例化」或「初始化」一個接口。你只是將一個變量定義爲你知道實現這個接口的東西。

你基本上是告訴其他程序員對這個代碼的工作,對於這種方法的其餘部分,你只對事實感興趣,定myDocDoc(即,一些滿足Doc接口)。這可以使編程更簡單,因爲IDE的自動完成現在僅向您顯示由此界面定義的方法,而不是SimpleDoc能夠執行的所有操作。

想象一下,您將來希望擴展功能,以便根據某些輸入實現Doc的不同實現。而不是明確創建SimpleDoc,你說:

Doc mydoc = docFactory.getByType(inputType); 

docFactory可以生產任何類型的Doc,這種方法並不真正關心什麼樣的被實例化,因爲它會像對待一個Doc不管。

+0

另一個巨大的優勢。如果您將來決定使用ComplexDoc或MySuperOptimizedDoc,則只需更改一行代碼的右側。 – user949300 2012-01-12 20:58:59

+0

@ user949300:可以說,改變一行代碼的右邊*和左邊並不是那麼困難。但是,通過首先編程接口,您不會邀請開發人員開始調用'SimpleDoc'上的方法,而這種方法無法在其他任何類型的'Doc'上執行。正如你指出的那樣,這有助於減少在Doc類型更改時需要執行的重構量。 – StriplingWarrior 2012-01-12 21:02:03

+0

謝謝,現在更清楚了!我喜歡這種練習如何幫助更清楚地使用對象的開銷知識,這真的有助於充實爲什麼使用這樣的某些實踐。 – Alex 2012-01-12 21:06:00

4

您無法創建接口,您在此處執行的操作是創建SimpleDoc類的對象mydoc,該類實現接口Doc。由於該類實現了此接口,因此您可以像處理該接口的實例一樣處理mydoc。這允許您訪問接口中的所有聲明的方法,這是在類SimpleDoc

如果實現,例如,您的文檔接口應該是這樣的:

public interface Doc { 
    void print(); 
} 

和你SimpleDoc類看起來像這樣:

public class SimpleDoc implements Doc { 

    public void clear() { ... } 

    @Override 
    public void print() { ... } 

} 

...那麼你只能訪問你print() - 方法mydoc -object。但你也可以這樣說:

SimpleDoc mydoc = new SimpleDoc(); 

...然後您也可以撥打電話clear()