為什麼阿裡巴巴建議開發者謹慎使用繼承?

来源:https://www.cnblogs.com/yunxi520/archive/2020/01/10/12176661.html
-Advertisement-
Play Games

本人免費整理了Java高級資料,涵蓋了Java、Redis、MongoDB、MySQL、Zookeeper、Spring Cloud、Dubbo高併發分散式等教程,一共30G,需要自己領取。傳送門:https://mp.weixin.qq.com/s/osB-BOl6W-ZLTSttTkqMPQ 從 ...


本人免費整理了Java高級資料,涵蓋了Java、Redis、MongoDB、MySQL、Zookeeper、Spring Cloud、Dubbo高併發分散式等教程,一共30G,需要自己領取。
傳送門:https://mp.weixin.qq.com/s/osB-BOl6W-ZLTSttTkqMPQ

 

從學習Java的第一天起,我們就知道Java是一種面向對象語言,而學習Java的第二天,我們就知道了面向對象的三大基本特性是:封裝、繼承、多態。

所以,對於很多開發者來說,繼承肯定都是不陌生的。但是,繼承一定適合所有的場景嗎?毫無忌諱的使用繼承來做代碼擴展真的好嗎?

為什麼《阿裡巴巴Java開發手冊》中有一條規定:謹慎使用繼承的方式進行擴展,優先使用組合的方式實現。

為什麼阿裡巴巴建議開發者謹慎使用繼承?

 

本文就來針對這些問題,簡單分析一下。

1

面向對象的復用技術

每個人在剛剛學習繼承的時候都會或多或少的有這樣一個印象:繼承可以幫助我實現類的復用。

所以,很多開發人員在需要復用一些代碼的時候會很自然的使用類的繼承的方式,因為書上就是這麼寫的(老師就是這麼教的)。

但是,其實這樣做是不對的。長期大量的使用繼承會給代碼帶來很高的維護成本。

前面提到復用,這裡就簡單介紹一下麵向對象的復用技術。

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

作為一門面向對象開發的語言,代碼復用是Java引人註意的功能之一。Java代碼的復用有繼承,組合以及代理三種具體的表現形式。

2

繼承

繼承(Inheritance)是一種聯結類與類的層次模型。指的是一個類(稱為子類、子介面)繼承另外的一個類(稱為父類、父介面)的功能,並可以增加它自己的新功能的能力,繼承是類與類或者介面與介面之間最常見的關係。

為什麼阿裡巴巴建議開發者謹慎使用繼承?

 

繼承是一種is-a關係。如蘋果是水果,狗是動物,哈士奇是狗。

3

組合

組合(Composition)體現的是整體與部分、擁有的關係。

為什麼阿裡巴巴建議開發者謹慎使用繼承?

 

組合是一種has-a的關係。如汽車有一個發動機,學校有一個老師等。

4

組合與繼承的區別

首先,從類的關係確定時間點上,組合和繼承是有區別的:

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

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

另外,代碼復用方式上也有一定區別:

繼承結構中,父類的內部細節對於子類是可見的。所以我們通常也可以說通過繼承的代碼復用是一種白盒式代碼復用。

如果基類的實現發生改變,那麼派生類的實現也將隨之改變。這樣就導致了子類行為的不可預知性。

組合是通過對現有的對象進行拼裝(組合)產生新的、更複雜的功能。因為在對象之間,各自的內部細節是不可見的,所以我們也說通過組合的代碼復用是黑盒式代碼復用。

因為組合中一般都定義一個類型,所以在編譯期根本不知道具體會調用哪個實現類的方法。

最後,Java中不支持多繼承,而組合是沒有限制的。就像一個人只能有一個父親,但是他可以有很很多輛車。

5

優缺點對比

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

6

為什麼組合優於繼承

相信很多人都知道面向對象中有一個比較重要的原則『多用組合、少用繼承』或者說『組合優於繼承』。

從前面的介紹已經優缺點對比中也可以看出,組合比繼承更加靈活,也更有助於代碼維護。其具有不破壞封裝性、具有更好的可擴展性、支持動態組合、整體類可以改變局部類的行為等優點。

所以,建議在同樣可行的情況下,優先使用組合而不是繼承。因為組合更安全,更簡單,更靈活,更高效。

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

另外,除了《阿裡巴巴Java開發手冊》,在很多其他資料中也有關於組合和繼承的介紹和使用約束:

繼承要慎用,其使用場合僅限於你確信使用該技術有效的情況。一個判斷方法是,問一問自己是否需要從新類向基類進行向上轉型。如果是必須的,則繼承是必要的。反之則應該好好考慮是否需要繼承。《Java編程思想》
只有當子類真正是超類的子類型時,才適合用繼承。換句話說,對於兩個類A和B,只有當兩者之間確實存在is-a關係的時候,類B才應該繼續類A。《Effective Java》


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 通過form表單上傳圖片時,有時候web容器對文件大小的限制會影響我們上傳。這時,前端頁面可以考慮將圖片轉換成base64串來實現上傳。 圖片與Base64的互轉,其實就是利用了文件流與Base64的互轉。 文件轉換成Base64字元串:讀取文件流,放到byte數組裡,對byte數組進行Base64 ...
  • ``` import imageio # 需要合在一起的圖片 image_list = [r'C:\Users\Hlzy\Desktop\\' + str(x) + ".jpg" for x in range(1, 12)] # gif的圖片名 gif_name = r'C:\Users\Hlzy\... ...
  • 、`Filter Servlet XSS`攻擊等。如果我們使用的是傳統的Spring MVC進行開發,那麼只需要在Tomcat的web.xml文件中進行如下配置即可: PS:在容器啟動的時候,上面三個組件啟動的順序是Listener Filter Servlet,這邊安利一個記憶的方法:把啟動順序記 ...
  • 本文檔介紹了要理解“使用 Python 進行地理處理”的幫助文檔需要掌握的一些辭彙。 ! 術語 說明 Python Python 是由 Guido van Rossum 在上世紀八十年代末構想並於 1991 年推出的一種開源編程語言。它最早集成於 ArcGIS 9.0 中,從此以後便成為用戶創建地理 ...
  • 配置好Dockerfile FROM openjdk:8-jdk-alpine ARG JAR_FILE=target/*.jar COPY ${JAR_FILE} app.jar ENTRYPOINT ["java","-jar","/app.jar"] 運行 meavn package 打開終端 ...
  • 歡迎大家關註我的微信公眾號,不定時更新 使用方法非常簡單,只需放到你的 utils.js 工具文件中,直接 export const 加上我的封裝方法,在別的文件中使用{方法1,方法2,方法3...}引用後就可以直接使用了! 001.輸入一個值,返回其數據類型 type = para => { re ...
  • 面向過程就是分析出解決問題所需要的步驟,然後用函數把這些步驟一步一步實現,使用 的時候一個一個依次調用就可以了;面向對象是把構成問題事務分解成各個對象,建立對 象的目的不是為了完成一個步驟,而是為了描敘某個事物在整個解決問題的步驟中的行為。 面向過程 理解為怎麼做,更註重過程的實現 1、首先把完成某 ...
  • 轉行的同學最關心的就是Python的薪資情況了。今天我們就來具體看一下Python現在的薪資情況。 這是一張網友統計的Python工程師工資情況圖表。詳細說明瞭現在Python工程師在各個城市的薪資情況。 ! 從圖中我們可以看到: 北京Python工程師平均薪資22K,是當之無愧的程式員最高薪的地方 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...