日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

OOP组合和继续的优缺点

發布時間:2023/12/18 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 OOP组合和继续的优缺点 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

—— 詳解繼承與組合的優缺點

組合與繼承都是提高代碼可重用性的手段。在設計對象模型時,可以按照語義來識別類之間的組合關系和繼承關系。在有些情況下,采用組合關系或者繼承關系能完成同樣的任務,組合和繼承存在著對應關系:組合中的整體類和繼承中的子類對應,組合中的局部類和繼承中的父類對應,如下圖:

組合:繼承:

一、基礎知識

我們先用代碼幫大家來理解一下組合和繼承:

1、對于已經存在Parent類時需要擴展其方法時

結構圖:

繼承代碼:

?

代碼 class?Parent
????{
????????public?void?Method1()?
????????{?
????????}
????????public?void?Method2()?{?}
????????public?void?Method3()?{?}
????}
?class?Child1:Parent
????{
????????public?void?MethodA()?{?}
????}
?class?Child2:Parent
????{
????????public?void?MethodA()?{?}
????}

?

組合代碼:

?

代碼 class?ComponentA
????{
????????Parent?p?=?new?Parent();
????????public?void?Method2()
????????{
????????????p.Method2();
????????}
????????public?void?MethodA()
????????{
????????}
????}
?class?ComponentB
????{
????????Parent?p?=?new?Parent();
????????public?void?Method2()?{
????????????p.Method2();
????????}
????????public?void?MethodB()
????????{?
????????}
????}

?

2、如果發現兩個類具有很多代碼相同的類需要抽象時,如下圖A,B兩個類,這兩個類中method1,和method3兩個方法代碼相同

繼承:

實現代碼:

?

代碼 class?A:C
????{
????????public?void?MethodB()?{?}
????????public?override?void?Method2()
????????{
????????????
????????}
????}
????class?B:C
????{
????????public?override?void?Method2()
????????{
????????????
????????}
????????public?void?MethodB()?{?}
????}
????class?C
????{
????????public?void?Method1()?{?}
????????public?virtual?void?Method2()?{?}
????????public?void?Method3()?{?}
????}

?

?

組合:

實現代碼:

?

代碼 class?A
????{
????????public?void?MethodA()?{?}
????????C?c?=?new?C();
????????public?void?Method1()
????????{
????????????c.Method1();
????????}
????????public?void?Method2()?{?}

????}
????class?B
????{
????????public?void?MethodB()?{?}
????????public?void?Method2()?{?}
????}
????class?C
????{
????????public?void?Method1()?{?}
????????public?void?Method2()?{?}
????????public?void?Method3()?{?}
????}

?

二、繼承與組合的優缺點

?

合 關 系

繼 承 關 系

優點:不破壞封裝,整體類與局部類之間松耦合,彼此相對獨立

缺點:破壞封裝,子類與父類之間緊密耦合,子類依賴于父類的實現,子類缺乏獨立性

優點:具有較好的可擴展性

缺點:支持擴展,但是往往以增加系統結構的復雜度為代價

優點:支持動態組合。在運行時,整體對象可以選擇不同類型的局部對象

缺點:不支持動態繼承。在運行時,子類無法選擇不同的父類

優點:整體類可以對局部類進行包裝,封裝局部類的接口,提供新的接口

缺點:子類不能改變父類的接口

缺點:整體類不能自動獲得和局部類同樣的接口

優點:子類能自動繼承父類的接口

缺點:創建整體類的對象時,需要創建所有局部類的對象

優點:創建子類的對象時,無須創建父類的對象

?

1、為什么繼承破壞封裝性:

?

鴨子中不想要“飛”的方法,但因為繼承無法封裝這個無用的“飛”方法 。

2、為什么繼承緊耦合:

?

當作為父類的BaseTable中感覺Insert這個名字不合適時,如果希望將其修改成Create方法,那使用了子類對象Insert方法將會編譯出錯,可能你會覺得這改起來還算容易,因為有重構工具一下子就好了并且編譯錯誤改起來很容易。但如果BaseTable和子類在不同的程序集中,維護的人員不同,BaseTable程序集升級,那本來能用的代碼忽然不能用了,這還是很難讓人接受的

3、為什么繼承擴展起來比較復雜

當圖書和數碼的算稅方式和數碼產品一樣時,而消費類產品的算稅方式是另一樣時,如果采用繼承方案可能會演變成如下方式:

這樣如果產品繼續增加,算稅方式繼續增加,那繼承的層次會非常復雜,而且很難控制,而使用組合就能很好的解決這個問題,參見:面向對象思想的頭腦風暴(一)

4、繼承不能支持動態繼承

這個其實很好理解,因為繼承是編譯期就決定下來的,無法在運行時改變,如3例中,如果用戶需要根據當地的情況選擇計稅方式,使用繼承就解決不了,而使用組合結合反射就能很好的解決。

5、為什么繼承?子類不能改變父類接口

如2中的圖

子類中覺得Insert方法不合適,希望使用Create方法,因為繼承的原因無法改變

?

三、如何使用繼承

?

1、精心設計專門用于被繼承的類,繼承樹的抽象層應該比較穩定,一般不要多于三層。

2、對于不是專門用于被繼承的類,禁止其被繼承。

3、優先考慮用組合關系來提高代碼的可重用性。

4、子類是一種特殊的類型,而不只是父類的一個角色

5、子類擴展,而不是覆蓋或者使父類的功能失效

?

?

四、組合的缺點:

1、整體類不能自動獲得和局部類同樣的接口

如果父類的方法子類中幾乎都要暴露出去,這時可能會覺得使用組合很不方便,使用繼承似乎更簡單方便。但從另一個角度講,實際上也許子類中并不需要暴露這些方法,客戶端組合應用就可以了。所以上邊推薦不要繼承那些不是為了繼承而設計的類,一般為了繼承而設計的類都是抽象類。

2、創建整體類的對象時,需要創建所有局部類的對象

這個可能沒什么更好的辦法,但在實際應用中并沒有多出多少代碼。

五、相關原則

1、里氏代換原則(LSP)(以下轉自http://www.cnblogs.com/zhenyulu/articles/36061.html)

Liskov Substitution Principle(里氏代換原則):子類型(subtype)必須能夠替換它們的基類型。

?

白馬、黑馬
?

反過來的代換不成立
《墨子·小取》說:"娣,美人也,愛娣,非愛美人也……"娣便是妹妹,哥哥喜愛妹妹,是因為兩人是兄妹關系,而不是因為妹妹是個美人。因此,喜愛妹妹不等同于喜愛美人。用面向對象語言描述,美人是基類,妹妹是美人的子類。哥哥作為一個有"喜愛()"方法,接受妹妹作為參數。那么,這個"喜愛()"方法一般不能接受美人的實例。

?

?

下邊那個長方形正方形的例子我就不轉了,大家可以到上邊那個博客地址中了解。

2、合成/聚合復用原則(CARP)(以下轉自http://www.cnblogs.com/zhenyulu/articles/36068.html)
合成/聚合復用原則(Composite/Aggregate Reuse Principle或CARP)經常又叫做合成復用原則(Composite Reuse Principle或CRP),就是在一個新的對象里面使用一些已有的對象,使之成為新對象的一部分;新對象通過向這些對象的委派達到復用已有功能的目的。

簡而言之,要盡量使用合成/聚合,盡量不要使用繼承。

o Design to interfaces.
o Favor composition over inheritance.
o Find what varies and encapsulate it.
(摘自:Design Patterns Explained)

區分"Has-A"與"Is-A"

"Is-A"是嚴格的分類學意義上定義,意思是一個類是另一個類的"一種"。而"Has-A"則不同,它表示某一個角色具有某一項責任。

導致錯誤的使用繼承而不是合成/聚合的一個常見的原因是錯誤的把"Has-A"當作"Is-A"。

例如:
?

實際上,雇員、經理、學生描述的是一種角色,比如一個人是"經理"必然是"雇員",另外一個人可能是"學生雇員",在上面的設計中,一個人無法同時擁有多個角色,是"雇員"就不能再是"學生"了,這顯然是不合理的。

錯誤源于把"角色"的等級結構與"人"的等級結構混淆起來,誤把"Has-A"當作"Is-A"。解決辦法:

?

?

總結:

根據我們前面講的內容我們可以發現繼承的缺點遠遠多于優點,盡管繼承在學習OOP的過程中得到了大量的強調,但并不意味著應該盡可能地到處使用它。相反,使用它時要特別慎重。只有在清楚知道繼承在所有方法中最有效的前提下,才可考慮它。?繼承最大的優點就是擴展簡單,但大多數缺點都很致命,但是因為這個擴展簡單的優點太明顯了,很多人并不深入思考,所以造成了太多問題,希望這篇文章能引發你一些思考。

轉載于:https://www.cnblogs.com/keyyang/p/3941548.html

總結

以上是生活随笔為你收集整理的OOP组合和继续的优缺点的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。