2012-06-14 63 views
2

可能重複:
Prefer composition over inheritance?繼承VS組成

我不知道,爲什麼(或在何種情況下)應在考慮繼承,而不是組合物時也有這麼多缺點:

  • 如果我們在調用超類方法的子類中實現/覆蓋方法,不保證我們的超類(可能是某個庫)的另一版本不會破壞我們的代碼
  • 如果在超類中出現一個具有與sublclass方法相同的簽名的新方法,但返回類型不同,我們的類不會編譯。

因此,我無法想象,地球上我們怎麼能依靠它。超類作者可能希望提高性能,並且我們的客戶端代碼可能會崩潰。

所以我的問題是:

  • 如何解決這些問題(例如,在標準的Java庫)?
  • 何時使用繼承和組合?
+2

http://stackoverflow.com/questions/49002/prefer-composition-over-inheritance?rq=1 http://stackoverflow.com/questions/216523/object-oriented-best-practices-inheritance-v-組合-v接口?rq = 1 http://stackoverflow.com/questions/1598722/should-i-use-inheritance-or-composition?rq=1 – adarshr

+0

好吧,但我仍然無法找到答案給我第一個問題。 – iozee

+2

您所描述的問題與組合與繼承問題無關。例如,如果一個方法簽名發生變化,*使用的任何*代碼將會破壞它,包括任何組合類中的任何委託方法。 – thkala

回答

6

您的第一個異議同樣適用於構圖:如果您調用方法的實現發生更改,則不能保證您的代碼不會中斷。

第二個反對意見實際上是一件好事,因爲您會立即注意到API的新版本存在問題。

該問題與繼承/組成沒有太大關係。如果一個類的公共契約從一個版本變爲另一個版本,那麼必須對代碼進行更改才能適應這些更改。通過避免後向不兼容的變化來解決問題。提供新的API可以是解決方案(例如,請參閱io,其次是nio,接下來是nio2)。否則,發行說明和遷移文檔可以幫助從一個API版本轉換到另一個版本。

當你的類和另一個類之間存在is-a關係時,使用繼承。當你的班級和其他班級之間存在一種關係時,使用組合。