繼承(inheritance) 是實現代碼重用的有力手段,但它并非永遠是完成這項工作的最佳工具.
在包的內部使用繼承是非常安全的.然而,對于普通的具體類進行跨越包邊界的繼承,則是非常危險的.
與方法調用不同的是,繼承打破了封裝性.
- 子類依賴于其超類中特定功能的實現細節.
- 超類在后續的版本中可以獲得新的方法.
避免上述問題: 不用擴展現有的類,而是在新的類中新增一個私有域,它引用現有類的一個實例. 這種設計被稱為"復合"(composition)
這樣得到的類會非常穩固,它不依賴于現有類的實現細節,即使現有的類添加了新的方法,也不會影響新的類.
只有當子類真正是超類的子類型時, 才適合繼承.
也就是對于兩個類A和B, 只有當兩者之間確實存在"is-a"關系的時候,類B才應該擴展A.
簡而言之, 繼承的功能非常強大,但是也存在諸多問題,因為它違背了封裝原則.只有當子類和超類之間確實存在子類型關系時,使用繼承才是恰當的. 即便如此, 如果子類和超類處在不同的包中, 并且超類并不是為了繼承而設計的, 那么繼承將會導致脆弱性. 為了避免這種脆弱性, 可以用復合和轉發機制來代替繼承,尤其是當存在適當的接口可以實現包裝類的時候. 包裝類不僅比子類更加健壯, 而且功能也更加強大.