本文轉自:http://changbl.iteye.com/blog/2304492 作者:空蘭幽谷
組合和繼承是面向對象中兩種代碼複用的方式。組合是指在新的類中創建原有類的對象,重複利用已有類的功能。繼承是面向對象的主要特徵之一,它允許設計人員根據其他類的實現來定義一個類的實現。組合和繼承都允許在新的類中設置子對象,只是組合是顯式的,而繼承則是隱式的。組合和繼承存在着對應關係:組合中的整體類和繼承中的子類對應,組合中的局部類和繼承中的父類對應。
二者的區別在哪裏呢?首先分析一個實例。Car表示汽車對象,Vehicle表示交通工具對象,Tire表示輪胎對象。三者的關係如圖所示。
從圖中可以看出,Car是Vehicle的一種,因此是一種繼承關係(又被稱爲“is - a”關係);而Car包含了多個Tire,因此是一種組合關係(又被稱爲“has - a”關係)。其實現方式如下:
繼承的實現方式:
- class Verhicle{
- }
- class Car extends Verhicle{
- }
組合的實現方式:
- class Tire{
- }
- class Car extends Verhicle{
- private Tire t = new Tire();
- }
既然繼承和組合都能實現代碼的重用,那麼在實際使用時又該如何選擇呢?一般情況下,遵循以下兩點原則:
1. 除非兩個類是“is - a”關係,否則不要輕易的使用繼承,不要單純的爲了實現代碼的重用而使用繼承,因爲過多的使用繼承會破壞代碼的可維護性。當父類被修改時,會影響到所有繼承自它的子類,從而增加程序的維護難度和成本。
2. 不要僅僅爲了實現多態而使用繼承。如果類之間沒有“is - a”關係,可以通過實現組合的方式來達到相同的目的。設計模式中的策略模式可以很好的說明這一點,採用接口和組合的方式比採用繼承的方式具有更好的可擴展性。
由於Java語言只支持單繼承,如果想同時繼承多個類,在Java中是無法直接實現的。同時,在Java語言中,如果使用繼承過多,也會讓一個class裏的內容臃腫不堪。所以,在Java語言中,能使用組合就儘量不要使用繼承。