深入理解Java中的組合和繼承


title: 深入理解Java中的組合和繼承
date: 2017-12-15 19:39:48
tags: javaSE
categories: javaSE

深入理解Java中的組合和繼承

前言

由於感覺自己對Java基礎知識有點遺忘,就找了一篇文章來鞏固一下。

面向對象的複用技術

複用性是面向對象技術帶來的很棒的潛在好處之一。如果運用的好的話可以幫助我們節省很多開發時間,提升開發效率。但是,如果被濫用那麼就可能產生很多難以維護的代碼。

作爲一門面向對象開發的語言,代碼複用是Java引人注意的功能之一。Java代碼的複用有繼承,組合以及代理三種具體的表現形式。本文將重點介紹繼承複用和組合複用。

繼承

繼承(Inheritance)是一種聯結類與類的層次模型。指的是一個類(稱爲子類、子接口)繼承另外的一個類(稱爲父類、父接口)的功能,並可以增加它自己的新功能的能力,繼承是類與類或者接口與接口之間最常見的關係;繼承是一種is-a關係。(圖片來自網絡,侵刪。)

Inheritance

組合

組合(Composition)體現的是整體與部分、擁有的關係,即has-a的關係。

Composition

組合與繼承的區別和聯繫

繼承結構中,父類的內部細節對於子類是可見的。所以我們通常也可以說通過繼承的代碼複用是一種白盒式代碼複用。(如果基類的實現發生改變,那麼派生類的實現也將隨之改變。這樣就導致了子類行爲的不可預知性;)

組合是通過對現有的對象進行拼裝(組合)產生新的、更復雜的功能。因爲在對象之間,各自的內部細節是不可見的,所以我們也說這種方式的代碼複用是黑盒式代碼複用。(因爲組合中一般都定義一個類型,所以在編譯期根本不知道具體會調用哪個實現類的方法)

繼承,在寫代碼的時候就要指名具體繼承哪個類,所以,在編譯期就確定了關係。(從基類繼承來的實現是無法在運行期動態改變的,因此降低了應用的靈活性。)

組合,在寫代碼的時候可以採用面向接口編程。所以,類的組合關係一般在運行期確定。

優缺點對比

組 合 關 系 繼 承 關 系
優點:不破壞封裝,整體類與局部類之間鬆耦合,彼此相對獨立 缺點:破壞封裝,子類與父類之間緊密耦合,子類依賴於父類的實現,子類缺乏獨立性
優點:具有較好的可擴展性 缺點:支持擴展,但是往往以增加系統結構的複雜度爲代價
優點:支持動態組合。在運行時,整體對象可以選擇不同類型的局部對象 缺點:不支持動態繼承。在運行時,子類無法選擇不同的父類
優點:整體類可以對局部類進行包裝,封裝局部類的接口,提供新的接口 缺點:子類不能改變父類的接口
缺點:整體類不能自動獲得和局部類同樣的接口 優點:子類能自動繼承父類的接口
缺點:創建整體類的對象時,需要創建所有局部類的對象 優點:創建子類的對象時,無須創建父類的對象

如何選擇

相信很多人都知道面向對象中有一個比較重要的原則『多用組合、少用繼承』或者說『組合優於繼承』。從前面的介紹已經優缺點對比中也可以看出,組合確實比繼承更加靈活,也更有助於代碼維護。

所以,

建議在同樣可行的情況下,優先使用組合而不是繼承。

因爲組合更安全,更簡單,更靈活,更高效。

注意,並不是說繼承就一點用都沒有了,前面說的是【在同樣可行的情況下】。有一些場景還是需要使用繼承的,或者是更適合使用繼承。

轉載自http://www.hollischuang.com/archives/1319

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章