2010-03-16 51 views
6

我是新來的Java,我已經看到了在許多地方,我的前輩已經宣佈代碼多態呼叫

List myList = new ArrayList();(選項1)

而不是

ArrayList myList = new ArrayList();(選項2)

你能告訴我爲什麼人們使用Option1,有沒有優勢?

如果我們使用option2,我們是否錯過了任何優點或功能?

回答

3

使用option1的優點是,即List myList = new ArrayList();與方法有關的多態行爲。說,例如,你可以有這需要類型列表參數的方法,

someMethod(List lst) 
{ 
    lst.doSomething(); 
    //do somethng else..... 
} 

在這種方法中lst可以Linked List類型,ArrayListCopyOnWriteArrayList的。

+0

@ Zaki,你可以爲我的技術網站做出貢獻嗎? – gmhk

+0

@harigm,Id喜歡。 – Zaki

+0

techification點com是網站,我在網站上工作,將更新您 – gmhk

10

選項1被認爲是編程到接口,其中選項2是編程到實施。後者有時是必需的,但前者爲您提供了通過確保不依賴特定實現提供的方法來輕鬆切換實現的能力。另外,如果你創建的方法只需要接口提供的功能,那麼它們應該被聲明爲需要接口,以便任何實現該接口的對象都可以傳遞給它們。這樣做擴大了重用API的範圍。例如:

// This can be called passing any List 
public int countItems(List lst, Filter flt) { 
    // iterate list, apply filter, and count matching objects 
    } 

// This can called passing only an ArrayList, an unnecessary limitation in this case 
public int countItems(ArrayList lst, Filter flt) { 
    // iterate list, apply filter, and count matching objects 
    } 

也就是說,對於某些接口,存在隱藏的實現相關陷阱(至少在Java中)。這個例子在List.get(int);如果你有一個ArrayList這是有效的,但是對於一個LinkedList它不是。如果該列表是非常大的差異是巨大的,尤其對於一個考慮不周的結構類似這樣的循環:

for(int xa=0,len=list.length; xa<len; xa++) { 
    Object obj=list.get(xa); 
    obj.doSomething(); 
    } 

這對於大型鏈表可怕的性能,因爲列表必須從一開始就對每個get(xa)遍歷。

+1

這個解釋很好,但我認爲在這裏提到Java集合框架的效率並不合適。 JCF的實現是關於算法的,而harigm正在談論OO原則 – phunehehe

+1

@Phunehehe:當OO原則直接關係到實現實現的透明替換時,似乎很適合在此討論潛在的陷阱。 –