2013-07-10 83 views
2

我一直將收集的數據結構實例化爲子實例並通過其父接口聲明。例如,聲明爲父接口並初始化爲子實例

Set<E> collection1 = new HashSet<E>(); 
Map<E> collection1 = new HashMap<E>(); 

這是什麼原因。子類將繼承所有的方法,並且從Java類文檔中提到的所有方法都會被覆蓋,但是具有相同的含義。那麼聲明它們的原因是他們的父界面。

任何投入將大大幫助我使我的基礎更強。


編輯

感謝您的反饋。我明白了。 但在改變

Set<E> collection1 = new HashSet<E>(); 

Set<E> collection1 = new LinkedHashSet<E>(); 

我們將失去我們的參考我們原來的HashSet的,因爲我們宣佈爲基準設置的新LinkedHashSet。那麼這樣做有什麼意義呢? 如果有什麼方法可以在不丟失數據的情況下將舊實現轉換爲新實現,那麼這將有意義。

回答

4

這被稱爲編碼到接口。這基本上是這樣做的,以便您可以稍後更改接口的底層實現,而不必在其他地方的代碼中進行任何更改。您可以稍後替換任何混凝土實施。

Set<E> collection1 = new LinkedHashSet<E>(); 

期望接口類型的任何方法或代碼都可以提供其任何實現類型。

有效的Java第二版,第52項:參照對象通過其接口

如果存在合適的接口類型,那麼參數,返回值和領域都應該使用接口類型聲明。如果你養成使用接口類型的習慣,你的程序將更加靈活。如果沒有合適的接口存在,則通過類引用對象是完全合適的。

這是Liskov substitution principle說:

可替代性是面向對象編程的一個原則。它指出,在一個計算機程序中,如果S是T的一個子類型,那麼類型T的對象可以用類型S的對象代替(即,類型S的對象可以代替類型T的對象),而不改變任何該程序的理想屬性(正確性,執行的任務等)。

有點我相信是你的代碼不應該依賴對象的實現細節,只是它的發佈的接口。

+0

也許值得一提的底層實現,也被稱爲「具體落實」爲好。 – Durandal

+0

@MagicMan注意到:) – NINCOMPOOP

1

的編譯器將變量作爲抽象類型(例如Set,這意味着如果需要的話,你可以在一個新的具體實現後交換(在JDK或你自己的)的各種設置實現之一。

這是良好的編程習慣,因爲它降低耦合。

它的正式名稱爲Liskov substitution principle