JWorld@TW the best professional Java site in Taiwan
      註冊 | 登入 | 全文檢索 | 排行榜  

» JWorld@TW » Software Design » Effective Java  

按列印兼容模式列印這個話題 列印話題    把這個話題寄給朋友 寄給朋友    訂閱主題
reply to postflat modego to previous topicgo to next topic
本主題所含的標籤
無標籤
作者 [Effective Java] 條款 14 : 優先考慮複合(compansition),然後才是繼承(inheritance)
metavige

metavige

版主

發文: 2134
積分: 10
於 2004-02-01 02:31 user profilesend a private message to usersend email to metavigereply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
繼承是實現"程式碼復用"的一條有力路徑,但他並非總是最佳選擇

繼承打破了"封裝性",換句話說,subclass的功能與其superclass的實作細節息息相關
除非superclass是"專門為擴展(extended)而設計",並帶良好的說明文件。

如果因為繼承而造成錯誤,解決方法可以用覆寫的方式來解決,但是這樣跟重新實作superclass的函式,這樣不但會困難、耗時,也容易出錯。

造成subclasses脆弱的一個原因是,其superclass可以取得後續版本的新函式。
我在想,有這樣一個情況:
1
2
3
4
5
6
7
8
9
10
11
12
13
public class ClassA {
  protected List package = new ArrayList();
  protected int i=0;
 
  public void add(Object o) {
    package.add(o);
    i--;
  }
 
  public Object get(int i) {
    return package.get(i);
  }
}


如果我繼承這個class:
1
2
3
4
5
6
7
8
9
public class ClassB extends ClassA {
  public void add(Object o) {
    super.add(o);
  }
 
  public Object get(int i) {
    return package.get(i);
  }
}

但是如果因為這樣,我去修改ClassA的add函式,可能就會造成 i 的值發生錯誤,就會變成跟當初不同的結果。我想之前那句話大概就是這種意思吧。

而且如果當 superclass 需要擴展函式,但是 subclass 卻已經有一個相同署名(signature)的函式,但不同的回返值型別,這樣子 subclass 就會沒辦法編譯∼

所以如果要避免之前所說的那些問題的話,就可以不要擴展現有的 class,而是為新的 class 添加一個 private 的 field,用來指向現有 class 的實體。這種設計稱為複合(composition)
新的 class 中的每一個 instance 函式都呼叫其內含"既有 class 實體"的相對應函式,並傳回其結果,這便是所謂的轉發(forwarding)[color=blue],而新 class 中的函式稱為[/color]轉發函式(forwarding method)

不過有時候 composition & forwarding 常被誤以為是 Delegate,除非 wrapper object(外覆物件)把自己傳遞給 wrapped object(被覆物件) (其實還沒看到這裡的時候,的確是會有這樣的疑問~)

所以,對於 classes A 和 B 而言,如果 "B 是一種 A" 的關係存在,B 才應該擴展 A。

如果再適合採用 "複合" 之處,你卻運用 "繼承",會非必要地暴露時做細節。導致 API 過分依賴原始實作細節,永遠限制你的 class 效率。

繼承將會傳播 superclass API 的所有缺陷,而複合允許你設計新的 API,隱藏 superclass 的缺陷。


metavige edited on 2004-02-02 01:00
reply to postreply to post
請各位新手參考 論壇規範Java 新手 FAQ
話題樹型展開
人氣 標題 作者 字數 發文時間
6555 [Effective Java] 條款 14 : 優先考慮複合(compansition),然後才是繼承(inheritance) metavige 1661 2004-02-01 02:31
5544 Re: 條款 14 : 優先考慮複合,然後才是繼承 frank 1646 2004-04-10 23:36
5995 Re: 條款 14 : 優先考慮複合,然後才是繼承 metavige 61 2004-04-12 21:49
» JWorld@TW »  Software Design » Effective Java

reply to postflat modego to previous topicgo to next topic
  已讀文章
  新的文章
  被刪除的文章
Jump to the top of page

JWorld@TW 本站商標資訊

Powered by Powerful JuteForum® Version Jute 1.5.8