当前位置: 首页 > 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.dtcms.com/a/301052.html

相关文章:

  • 商品中心—1.B端建品和C端缓存
  • 内网服务器实现从公网穿透
  • NVMe高速传输之摆脱XDMA设计16:队列管理模块设计(上)
  • Python 列表推导式与生成器表达式
  • 激光SLAM技术综述(2025版)
  • Python入门构建网页
  • Linux驱动20 --- FFMPEG视频API
  • 基于Django的天气数据可视化分析预测系统
  • Coze:字节跳动AI开发平台功能和架构解析
  • 第五章 中央处理器(CPU)知识体系与考法总结
  • 虚拟机ubuntu20.04共享安装文件夹
  • ubuntu 部署 coze-loop
  • C语言函数递归详解
  • 运行时长和内存优化:混合精度训练(MPT)案例和梯度检查点(GCP)
  • LWGJL教程(6)——GL20源码
  • Python初学OpenCV:图像预处理进阶指南(二)
  • 使用frp实现免费内网穿透
  • 【2025CVPR-扩散模型方向】TKG-DM:免训练的色度关键内容生成扩散模型
  • 区块链:工作量证明与联邦学习
  • ArkTS 模块通信全解析:用事件总线实现页面消息联动
  • rapidocr v3.3.0发布了
  • [10月考试] D
  • 【lucene】MMapDirectory 在FSDirectory基础上干了啥?
  • 链表算法综合——重排链表
  • KNN 算法中的各种距离:从原理到应用
  • D3.js的力导向图使用入门笔记
  • AI行业热点抓取和排序系统实现案例
  • [Linux入门] Linux 远程访问及控制全解析:从入门到实战
  • Jmeter的元件使用介绍:(七)后置处理器详解
  • 10.迭代器模式