当前位置: 首页 > news >正文

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.xdnf.cn/news/1196533.html

相关文章:

  • 影刀RPA_初级课程_玩转影刀自动化_网页操作自动化
  • 【机器学习深度学习】NLP评价指标 BLEU 和 ROUGE
  • python优秀案例:基于python flask实现的小说文本数据分析与挖掘系统,包括K-means聚类算法和LDA主题分析
  • 用KNN实现手写数字识别:基于 OpenCV 和 scikit-learn 的实战教学 (超级超级超级简单)
  • Kafka——消费者组消费进度监控都怎么实现?
  • 牛客周赛101 D题 题解
  • 五、搭建springCloudAlibaba2021.1版本分布式微服务-gateway网关
  • 力扣热题100----------53最大子数组和
  • 零基础学习性能测试第五章:Tomcat的性能分析与调优-Tomcat原理,核心配置项,性能瓶颈分析,调优
  • RAG(检索增强生成)
  • 探秘CommonJS:Node.js模块化核心解析
  • redis主从复制、哨兵机制底层原理
  • XML Schema 指示器:全面解析与深度应用
  • 齐护Ebook科技与艺术Steam教育套件 可图形化micropython Arduino编程ESP32纸电路手工
  • xgboost 机器学习在生物信息学中的应用
  • 【橘子分布式】gRPC(番外篇-客户端重试机制)
  • PostGIS面试题及详细答案120道之 (021-030 )
  • Java面试精进:测试、监控与序列化技术全解析
  • Netty中 ? extends Future<? super V>这种的写法的理解
  • 51c自动驾驶~合集9
  • Java面试宝典:MySQL执行原理二
  • Spring AI 项目实战(二十一):Spring Boot + AI +DeepSeek驱动的智能题库系统(附完整源码)
  • bash的特性-常用的通配符
  • AWS免费套餐全面升级:企业降本增效与技术创新解决方案
  • HCIP---MGRE实验
  • 电子电气架构 --- 软件bug的管理模式
  • logstash采集springboot微服务日志
  • 【奔跑吧!Linux 内核(第二版)】第4章:内核编译和调试
  • 商汤发布具身智能平台,让机器人像人一样和现实世界交互
  • Agent大模型大厂面试题及讲解答案