看過很多面向對象設計的書,一般都使用這種方法幫我們判斷是選擇繼承還是選擇組合:“is-a 關係選擇繼承,has-a關係選擇組合”。
但是這個只是初期的一般指導,我認爲還有另一個因素:從到底是擴展父類接口還是壓縮父類接口考慮。
考慮下面這個經典設計問題:有矩形類和正方形類,他們之間是否該使用繼承?
正方形就是一個特殊的矩形,按照前面的方法,應該從矩形類繼承沒有問題。但是經典的設計解決方案沒有這樣做,而是把這兩個類放在了同一個層次。(具體是哪本書忘了)
分析原因:
正方形是一個矩形,沒錯。但是正方形不應該像矩形一樣既有設置長的操作,也有設置寬的操作。所以正方形需要的接口其實小於矩形的接口,如果強制使其接口擴大,只會使人對正方形的概念模糊。
其實,我們再來真正考慮一下到底繼承做了些什麼:增加屬性、擴大接口。而這裏正方形剛好兩個都不需要。
同時,我們也可以看到使用繼承關係時,這種一般和特殊的關係是通過增加屬性和操作來做的。這種一般和特殊關係沒有考慮到另一點:有時候特殊是對一般的某些一般性進行限制的。這裏正方形就是對矩形本身的東西進行限制,限制其長寬相等。這不是通過增加某些東西來特殊話,而是改變原來的東西進行的特殊化。這種情況下,繼承就是一個不好的解決方案。
by:kangtian0
附:
其實單純給類增加屬性的時候,這時候還面臨另一個選擇方案:使用Decorator模式。這種情況下選擇Decotator模式還是繼承是競爭的,根據你的需要而定。