天天看點

【筆記64】通過接口引用對象

第40條有一個建議:應該使用接口而不是用類作為參數類型。即應該優先使用接口而不是類來引用對象。如果有合适的接口類型存在,那麼對于參數、傳回值、變量和域來說,就都應該使用接口類型進行聲明。

隻有當你利用構造函數建立某個對象的時候,才真正需要引用這個對象的類。

考慮Vector的情形,它是List接口的一個實作,在聲明變量的時候應該養成這樣的習慣:

//Good - use interface as type
        List<?> list= new Vector<?>();
           

而不是像這樣的聲明:

//Bad - use class as type
        Vector<?> list= new Vector<?>();

           

如果一個類實作了多個接口,用接口類型來定義它的引用變量的話,一眼就可以明白,這裡是需要這個類的哪些方法。

同時使程式更加靈活。當你決定更換實作時,隻要改變構造器中類的名稱。其他使用list地方的代碼不需要改動。如下:

List<?> list= new ArrayList<?>();
           

注意:但是如果你後面的代碼依賴與Vector類的某些特性,如同步政策,這是就不應該簡單的将Vector更換為ArrayList。

适合于用類來引用對象的情形:

  • 如果沒有合适的接口存在,可以用類來引用對象。例如,考慮值類(String、BigInteger)很少會用多個實作編寫,他們通常是final的,并且很少有對應的接口。使用這種值類作為參數、變量、域或者傳回值類型就比較合适。
  • 對象屬于一個架構,而架構的基本類型是類,不是接口。如果對象屬于這種基于類的架構,就應該用相關的基類(往往是抽象類)來引用對象,而不是它的實作類。例如java.util.TimerTask抽象類。
  • 類實作了接口,但是它提供了接口中不存在的額外方法。例如LinkedHashMap,程式依賴于這些額外的方法,這種類就應該隻被用來引用它的執行個體。

以上這些例子并不全面,而隻是代表了一些“适合于用類來引用對象”的情形

總結:給定的對象是否具有适當的接口應該是很明顯的。如果是,用接口引用對象就會使程式更加靈活;如果不是,則使用類層次結構中提供了必要功能的最基礎的類。

繼續閱讀