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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈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)领域正式迈…