讀《Effective java 中文版》(15)

來源:互聯網
上載者:User
讀《Effective java 中文版》(15)

第14條:複合優先於繼承

  繼承是實現代碼重用的有力手段,但不適當地使用繼承會導致脆弱的軟體。

  • 在一個包內使用繼承是非常安全的,因在那兒子類和超類在同一個程式員的控制之下。
  • 對於專門為了繼承而設計、且有很好文檔說明的類,使用繼承也是安全的。
  • 對普通的具體類(concret class)時行跨躍包邊界的繼承,則是非常危險的。

  與方法調用不同的是,繼承打破了封裝性,一個子類依賴於其超類中特定功能的實現細節。超類的實現的變化,則子類可能會被打破。

  • 自用性,即超類中不同公有方法的實現時存在調用關係,當子類改寫這些方法時,常會導致子類的脆弱
  • 超類在它的後續方法中增加了新的方法,如果子類不能及時改寫這些方法,異常的資料或操作出現。
  • 子類繼承超類後,增加了一個新的方法,則當超類在新版中也增加了具有相同原型特徵的方法時,可能會出現問題

  有一種辦法可以避免上述所有問題:新類,不是擴充一個已有類,而是設定一個私人域,它引用這個已有類的一個執行個體。這種設計被稱為“複合(composition)”。新類中的每個執行個體方法,都可以調用被包含的已有類執行個體中對應的方法,並返回它的結果,即為“轉寄方法(forwarding method)”。這樣的類比較穩固,這不依賴於已有類的實現細節。一個類的執行個體都把另一個類的實現封裝起來了,則前者的類叫做封裝類(wrapper class)。

  看一個例子:

//wrapper class - uses composition in place of inheritance

public class InstrumentedSet implements Set{

private final Set s;

private int addCount=0;

public InstrumentedSet(Set s){

this.s=s;

}

public boolean add(Object o){

addCount++;

return s.add();

}

public boolean addAll(Collection c){

addCount+=c.size();

return s.addAll(c);

}

public int getAddCount(){

return addCount;

}

//forwarding methods

public void clear() { s.clear(); }

public boolean contains(Object o){return s.contains(o); }

public boolean isEmpty() {return s.isEmpty(); }

public int size() {return s.size(); }

....

public String toString() {return s.toString(); }

}

  上例中,InstrumentedSet類對Set類進行了修飾,增加了計數特性。有時,複合和轉寄這兩項技術的結合被錯誤地引用為“委託(delegation)”,從技術的角度而言,這不是委託,除非封裝對象把自己傳遞給一個被封裝的對象。

  封裝類幾乎沒有什麼缺點。需要注意的是,封裝類不適合用於回調架構(callback framework)中。在回調架構中,對象把自己的引用傳遞給其它的對象,以便將來調用回來,當它被封裝起來以後,它並不知道外面的封裝對象的情況,所以它傳遞一個指向自己的引用(this)時,會造成回調時繞開外面的封裝對象的問題。這被稱為SELF問題。

  只有當子類真正是超類的“子類型(subtype)”時,繼承才是合適的。即兩者之存在“is-a”的關係。java平台中,也有違反這條規則的地方:如Stack不是向量,所以不應擴充Vector;屬性列表不是散列表,所以Properties不應擴充Hashtable。在決定使用複合還是擴充時,還要看一試圖擴充的類的API有沒有缺陷,如果你願意傳播這些缺陷到自己的API中,則用繼承,否則可用複合來設計一個新的API。

Posted by Hilton at February 14, 2004 09:21 PM | TrackBack

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.