-
一:繼承
繼承按現有類創建一個對象,不改變現有類,採用現有類的形式向其中添加新代碼;(編譯器強制你去初始化基類,是is_a 的關係,比如說Student繼承Person,則說明Student is a Person。
繼承的優點是子類可以重寫父類的方法來方便地實現對父類的擴展。
繼承的缺點有以下幾點:
①:父類的內部細節對子類是可見的。
②:子類從父類繼承的方法在編譯時就確定下來了,所以無法在運行期間改變從父類繼承的方法的行爲。
③:如果對父類的方法做了修改的話(比如增加了一個參數),則子類的方法必須做出相應的修改。所以說子類與父類是一種高耦合,違背了面向對象思想。
二:組合
組合是在新類中使用現有類的對象,也就是設計類的時候把要組合的類的對象加入到該類中作爲自己的成員變量。組合是has_a 的關係。
組合的優點:
①:當前對象只能通過所包含的那個對象去調用其方法,所以所包含的對象的內部細節對當前對象時不可見的。
②:當前對象與包含的對象是一個低耦合關係,如果修改包含對象的類中代碼不需要修改當前對象類的代碼。
③:當前對象可以在運行時動態的綁定所包含的對象。可以通過set方法給所包含對象賦值。
組合的缺點:①:容易產生過多的對象。②:爲了能組合多個對象,必須仔細對接口進行定義。
由此可見,組合比繼承更具靈活性和穩定性,所以在設計的時候優先使用組合。
只有當下列條件滿足時才考慮使用繼承:
子類是一種特殊的類型,而不只是父類的一個角色
子類的實例不需要變成另一個類的對象
子類擴展,而不是覆蓋或者使父類的功能失效InheritTest.java 使用繼承方式實現目標
CompositeTest.java 使用組合方式實現目標
組合和繼承都允許在新的類中放置子對象,組合是顯式地這樣做,而繼承則是隱式地這樣做。
繼承是"is-a"關係
組合是"has-a"關係
1)組合(has-a)關係可以顯式地獲得被包含類(繼承中稱爲父類)的對象,而繼承(is-a)則是隱式地獲得父類的對象,被包含類和父類對應,而組合外部類和子類對應。
2)組合關係在運行期決定,而繼承關係在編譯期就已經決定了。
3)組合是在組合類和被包含類之間的一種鬆耦合關係,而繼承則是父類和子類之間的一種緊耦合關係。
4)當選擇使用組合關係時,在組合類中包含了外部類的對象,組合類可以調用外部類必須的方法,而使用繼承關係時,父類的所有方法和變量都被子類無條件繼承,子類不能選擇。
5)最重要的一點,使用繼承關係時,可以實現類型的回溯,即用父類變量引用子類對象,這樣便可以實現多態,而組合沒有這個特性。
6)還有一點需要注意,如果你確定複用另外一個類的方法永遠不需要改變時,應該使用組合,因爲組合只是簡單地複用被包含類的接口,而繼承除了複用父類的接口外,它甚至還可以覆蓋這些接口,修改父類接口的默認實現,這個特性是組合所不具有的。
7)從邏輯上看,組合最主要地體現的是一種整體和部分的思想,例如在電腦類是由內存類,CPU類,硬盤類等等組成的,而繼承則體現的是一種可以回溯的父子關係,子類也是父類的一個對象。8)這兩者的區別主要體現在類的抽象階段,在分析類之間的關係時就應該確定是採用組合還是採用繼承。
9)引用網友的一句很經典的話應該更能讓大家分清繼承和組合的區別:組合可以被說成“我請了個老頭在我家裏幹活” ,繼承則是“我父親在家裏幫我幹活"。
10)組合技術通常是用於在新類中使用現有類的功能而非它的接口的情形。
三、代理
代理是繼承和組合的中庸之道。將一個成員對象置於要構造的類中(就像組合),與此同時在新類中暴露了該類成員所有的方法(就像繼承)。
(組合+繼承)java中沒有直接的支持代理,(將基類對象作爲代理類的成員,而代理類有對應於基類的所有方法,各方法內使用基類對象成員調用基類的方法。)
代理的實例一:
輸出結果:
hello world!
YES!
hello world!
hello world!
hello 繼承!
hello stop!
圖文總結:
版權聲明:更多請參考:http://blog.csdn.net/yangquanhui1991,我們一起每天進步一點點!