java開閉原則 open-closed principle

基本知識

1.核心思想:面向抽象編程
2.基本內涵:對修改關閉,對擴展開放
3.要求:盡可能不修改源碼而是增加新功能

例子

以spring5核心原理與30個類手寫實戰中的為例

package com.gupaoedu.vip.design.principle.openclose;/*** Created by Tom*/
public interface ICourse {Integer getId();String getName();Double getPrice();
}
package com.gupaoedu.vip.design.principle.openclose;/*** Created by Tom*/
public class JavaCourse implements ICourse{private Integer Id;private String name;private Double price;public JavaCourse(Integer id, String name, Double price) {this.Id = id;this.name = name;this.price = price;}public Integer getId() {return this.Id;}public String getName() {return this.name;}public Double getPrice() {return this.price;}}
package com.gupaoedu.vip.design.principle.openclose;/*** Created by Tom*/
public class JavaDiscountCourse extends JavaCourse {public JavaDiscountCourse(Integer id, String name, Double price) {super(id, name, price);}public Double getDiscountPrice(){return super.getPrice() * 0.61;}//    public Double getOriginPrice(){
//        return super.getPrice();
//    }
//
//    public Double getPrice(){
//        return super.getPrice() * 0.61;
//    }}
package com.gupaoedu.vip.design.principle.openclose;/*** Created by Tom.*/
public class OpenCloseTest {public static void main(String[] args) {ICourse iCourse = new JavaDiscountCourse(232, "【咕泡學院】Java架構師專題課", 11800D);JavaDiscountCourse javaCourse = (JavaDiscountCourse) iCourse;System.out.println("課程ID:" + javaCourse.getId() +"\n課程名稱:《" + javaCourse.getName() + "》" +"\n原價:" + javaCourse.getPrice()  + "元" +"\n折后價:" + javaCourse.getDiscountPrice() + "元");//        ICourse iCourse = new JavaDiscountCourse(232, "【咕泡學院】Java架構師專題課", 11800D);
//        JavaDiscountCourse javaCourse = (JavaDiscountCourse) iCourse;
//        System.out.println("課程ID:" + javaCourse.getId() +
//                "\n課程名稱:《" + javaCourse.getName() + "》" +
//                "\n原價:" + javaCourse.getOriginPrice()  + "元" +
//                "\n折后價:" + javaCourse.getPrice() + "元");}
}

這里的javaDiscountCourse就是繼承了javaCourse,實現功能拓展,新增了一個折扣功能
至于注釋掉的getPrice()方法

//    public Double getPrice(){
//        return super.getPrice() * 0.61;
//    }

也是符合開閉原則的,因為它通過重寫父類方法來改變行為,而沒有修改父類。在這種情況下,JavaDiscountCourse 就不僅僅是拓展,而是改變了父類行為。
不過具體場景推薦使用getDiscountPrice(),因為職責單一清晰,getPrice()方法表示原始價格,getDisountPrice表示折扣價格,職責分離,代碼更清晰易懂
,同時也可以避免歧義,getPrice()如果也可能獲得打折價格,則可能讓調用者混亂。
總體上:JavaDiscountCourse 通過繼承并新增方法的方式,在不修改 JavaCourse 現有代碼的基礎上,實現了獲取打折價格的功能,完美體現了開閉原則的精神

對于測試類中的方法:

JavaDiscountCourse javaCourse = (JavaDiscountCourse) iCourse; // 這里進行了向下轉型

這里進行了向下轉型,為了調用 JavaDiscountCourse 特有的 getDiscountPrice() 方法,不得不將 ICourse 類型的引用強制轉換為 JavaDiscountCourse 類型。缺點來說,一方面破壞了原本的多態,畢竟使用javaDiscountCourse賦值給ICourse目的是為了使用多態,但是向下轉型則退化了這種優勢。而且也可能導致ClassCastException,需要判斷對象是不是對應的類的實例。此外,getDiscountPrice()方法緊耦合于類javaDiscountCourse,不利于統一管理。
我們借鑒之前注釋的getPrice方法,既然獲取價格這種需求是很常見的,那么我們自然可以抽象到接口中。我們為了避免混淆,可以換個名字:
比如getActualPrice(),即獲取實際價格

public interface ICourse {Integer getId();String getName();Double getPrice(); // 原始價格Double getActualPrice(); // 新增方法:獲取實際支付價格 (可能是原價,也可能是優惠價)
}public class JavaCourse implements ICourse {// ...@Overridepublic Double getActualPrice() {return getPrice(); // 對于原價課程,實際價格就是原價}
}public class JavaDiscountCourse extends JavaCourse {// ...@Overridepublic Double getActualPrice() {return super.getPrice() * 0.61; // 對于打折課程,實際價格是折后價}
}

這樣,在 OpenCloseTest 中,只需要:

ICourse iCourse = new JavaDiscountCourse(232, "【咕泡學院】Java架構師專題課", 11800D);
System.out.println("課程ID:" + iCourse.getId() +"\n課程名稱:《" + iCourse.getName() + "》" +"\n原價:" + iCourse.getPrice()  + "元" +"\n實際支付價:" + iCourse.getActualPrice() + "元");
// 這里就不需要向下轉型了,因為 getActualPrice() 是接口方法

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/91358.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/91358.shtml
英文地址,請注明出處:http://en.pswp.cn/web/91358.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

擁抱智慧物流時代:數字孿生技術的應用與前景

概述 在數字經濟全面推進的當下,物流行業正經歷著前所未有的智能化升級。作為新一代信息技術的重要代表,數字孿生技術正悄然改變著物流的運作方式和決策模式。所謂數字孿生,是指在虛擬空間中創建與現實物流系統高度一致的數字模型&#xff0…

libnest2d-頭文件分析-libnest2d.hpp-幾何類型-策略類型-參數配置

libnest2d 庫的主頭文件,定義了一個用于 二維不規則形狀自動排樣(Nesting) 的C接口。以下是詳細解析:1. 頭文件結構 (1) 防止重復包含 #ifndef LIBNEST2D_HPP #define LIBNEST2D_HPP // ... #endif // LIBNEST2D_HPP確保頭文件只被…

【Docker】部署Docker可視化管理面板Dpanel

一、DPanel 介紹 1.1 DPanel 簡介 DPanel 是一款專為 Docker 設計的可視化管理面板,旨在降低容器、鏡像及相關資源的管理門檻。通過簡潔直觀的圖形化界面,即使是對 Docker 不熟悉的用戶,也能輕松上手,實現容器化應用的高效部署與管…

GCC/G++ + Makefile/make 使用

一、gcc\g編譯器 什么是gcc和g,它們的區別又是什么? gcc編譯器是專門用來編譯C語言的,而g編譯器既可以編譯C語言又可以用來編譯C,但是主要還是用來編譯C。 我們都知道代碼形成可執行程序都是需要經過預處理、編譯、匯編和鏈接這四…

重復文件查找工具:DataSecurity Plus 全面提升企業文件管理效率

企業日常運營經常會出現這樣的場景:員工在文件傳輸、共享與備份過程中,因操作不當或系統設置問題,出現文件重復存儲;跨部門協作時,相同的項目資料可能被多次保存;隨著數據遷移與系統升級,重復文…

【軟件架構】資源池架構設計中的三種主流模式

在資源池架構設計中,三種主流模式——集中式、分布式和混合式資源池——各有其獨特的優勢、劣勢和適用場景。理解它們的區別對于設計高效、可靠和可擴展的系統至關重要。 下面是對這三種模式的詳細分析和比較:集中式資源池 核心概念: 將所有計…

Java 類加載沖突

在某次線上部署過程中,我們遇到了一個十分詭異的問題:同樣的應用,在 ext3 文件系統下運行正常,但部署到 ext4 文件系統下卻出現了如下異常:The methods class, com.ctc.wstx.io.StreamBootstrapper, is available from…

VMware安裝 統信UOS桌面專業版

前言 近年來,隨著Linux發行版在開發者、企業環境中的應用逐漸增多,國產操作系統統信UOS(基于Debian)因其良好的圖形化界面和本地化支持,成為不少用戶體驗Linux生態的選擇之一。本文將以VMware Workstation Pro 17為例…

SAP Datasphere 02 - 建模

創建連接創建到 HANA Cloud 實例的連接查看 HANA Cloud實例連接 Endpoint創建連接選擇連接類型配置連接信息,授權方式,用戶名密碼等配置連接名稱驗證連接導入數據源表創建目錄 Hotel ,放置建模對象點擊新建目錄,導入遠程表選擇數據…

isasssim robotiq夾爪踩坑

1. usd導出urdf失敗在isasssim的仿真中的 robotiq 2f夾爪,首先目前4.5asset里面的usd不能直接轉urdf,因為模型中存在 “閉環連接”,即某個部件(或關節)同時與兩個及以上的父部件相連,形成類似 “三角形” 的…

50天50個小項目 (Vue3 + Tailwindcss V4) ? | Pokedex(寶可夢圖鑒)

📅 我們繼續 50 個小項目挑戰!—— Pokedex組件 倉庫地址:https://github.com/SunACong/50-vue-projects 項目預覽地址:https://50-vue-projects.vercel.app/ 使用 Vue 3 結合 PokeAPI 來創建一個炫酷的寶可夢圖鑒應用。通過這個…

【Practical Business English Oral Scene Interpretation】在職主持會議-安排任務+結束會議

文章目錄Introduction1. 討論代辦事項2. 分配工作任務3. 說明截止日期4. 說明截止日期5. 感謝參會者Introduction Note that each row of the table represents the content of the conversation in order. 1. 討論代辦事項 AlexBarryNoteLet’s review the to-dos from the…

ansible簡單playbook劇本例子

1. 創建主機清單vim inventory.ini192.168.100.181[web:vars] ansible_userroot ansible_passwordAdmin123456[web] 192.168.100.1822. 創建一個簡單的劇本vim playbook.yaml- name: My first playhosts: webtasks:- name: Ping my hostsansible.builtin.ping:- name: Print me…

愛心煙花浪漫立方體輪播圖 - 用代碼表達愛意

項目介紹 這是一個專為表白和營造浪漫氛圍而設計的3D立方體輪播圖結合了現代Web技術與浪漫元素,通過立方體的旋轉展示珍貴的照片,同時配有愛心飄動、流星劃過、煙花綻放和雪花飛舞等浪漫特效,為你的表白增添獨特的科技浪漫。 效果展示截圖原…

基于人工智能的無人機網絡系統

目錄 1.環境感知與目標檢測 2.無人機定位與導航(SLAM與路徑規劃) 3.無人機網絡通信與資源優化 4.無人機集群協同控制(一致性與編隊) 5.無人機任務分配與調度(組合優化) 6.MATLAB仿真測試 基于人工智能…

nginx安裝配置Lua模塊的支持

一、先來看幾個概念問題1.1 為什么需要?nginx官方自帶了非常多的核心模塊,再加上第三方的模塊能夠滿足我們大部分的業務需要,但是業務的需求、業務的場景變化需要添加一些額外的功能,如果自己去開發一個nginx模塊相對來說比較笨重…

智慧礦山低光照識別準確率↑32%:陌訊多模態融合算法實戰解析

原創聲明本文為原創技術解析,核心技術參數與架構引用自《陌訊技術白皮書》,禁止未經授權的轉載與商用。一、行業痛點:智慧礦山的視覺識別困境礦山場景的視覺監控一直面臨多重技術挑戰:井下巷道長期處于低光照環境(光照…

AI賦能操作系統:通往智能運維的未來

一、具備AI能力的操作系統未來的操作系統如果具備了AI能力,那將徹底改變我們管理和保護服務器的方式。一旦AI能力被充分集成并啟用,自動優化、安全檢測和漏洞修復的潛力將變得無比巨大且切實可行。想象一下未來的服務器管理:不再需要人工夜以…

sqli-labs:Less-13關卡詳細解析

1. 思路🚀 本關的SQL語句為: $sql"SELECT username, password FROM users WHERE username($uname) and password($passwd) LIMIT 0,1";注入類型:字符串型(單引號、括號包裹)、POST請求提示:參數…

微軟發布Microsoft Sentinel數據湖國際版

在網絡安全威脅持續升級的背景下,微軟宣布推出Microsoft Sentinel數據湖(國際版),以突破性架構重塑企業安全運營能力。該產品目前已進入公開預覽階段,標志著安全信息與事件管理(SIEM)領域正式邁…