参考慕课网视频《Java设计模式精讲》:
视频作者:Geely
视频链接:https://coding.imooc.com/lesson/270.html#mid=17147
定义
一个软件实体,如类、模块、函数应该对扩展开放,对修改关闭。
强调
用抽象构建框架,用实现扩展细节。
ps:抽象灵活性好,适应性广,只要抽象的合理,可以基本保持软件架构的稳定。而软件中易变的细节,我们用从抽象派生的实现类来进行扩展,当软件需要发生变化时,我们只需要根据需求重新派生一个实现类来扩展就可以了。
优点
提高软件系统的可复用性及可维护性。
就用简洁的代码实现开闭原则。
定义一个接口。
package com.qfcwx.openclose;
/**
* @ClassName: Course
* @Author: 清风一阵吹我心
* @Description: TODO
* @Date: 2019/4/7 16:29
* @Version 1.0
**/
public interface Book {
/**
* 获取id
*
* @return
*/
Long getId();
/**
* 获取名称
*
* @return
*/
String getName();
/**
* 获取价格
*
* @return
*/
Double getPrice();
}
接着定义其实现类
package com.qfcwx.openclose;
/**
* @ClassName: JavaBook
* @Author: 清风一阵吹我心
* @Description: TODO
* @Date: 2019/4/7 16:31
* @Version 1.0
**/
public class JavaBook implements Book {
private Long id;
private String name;
private Double price;
public JavaBook(Long id, String name, Double price) {
this.id = id;
this.name = name;
this.price = price;
}
@Override
public Long getId() {
return this.id;
}
@Override
public String getName() {
return this.name;
}
@Override
public Double getPrice() {
return this.price;
}
}
接下来编写测试类
package com.qfcwx.openclose;
import org.junit.Test;
/**
* @ClassName: MainTest
* @Author: 清风一阵吹我心
* @Description: TODO 测试类
* @Date: 2019/4/7 16:36
* @Version 1.0
**/
public class MainTest {
@Test
public void testMethod1() {
Book book = new JavaBook(110L, "《Java编程思想》", 78D);
System.out.println(book.getName() + "这本书值得每一个开发者反复品读" + ",书的编号是" + book.getId() + ",售价" + book.getPrice());
}
}
使用的junit测试,代码很简单,通过构造函数初始化数据,然后赋值,打印值。
倘若,我们要获取这本书的打折价格怎么办。是直接修改接口?还是直接在实现类中增加新的方法?
当对接口修改的时候,破坏了其稳定性。而且所有实现它的子类,都要进行修改,不利于代码的维护。
所以,我们可以创建一个JavaBook的子类。给它添加一个打折的方法。
package com.qfcwx.openclose;
/**
* @ClassName: JavaDiscountBook
* @Author: 清风一阵吹我心
* @Description: TODO 打折后的价格
* @Date: 2019/4/7 16:46
* @Version 1.0
**/
public class JavaDiscountBook extends JavaBook {
public JavaDiscountBook(Long id, String name, Double price) {
super(id, name, price);
}
/**
* 打折
*
* @return
*/
public Double getDiscountPrice() {
return super.getPrice() * 0.8;
}
}
新增测试方法。
@Test
public void testMethod2() {
Book book = new JavaDiscountBook(110L, "《Java编程思想》", 88D);
JavaDiscountBook javaDiscountBook = (JavaDiscountBook) book;
System.out.println(javaDiscountBook.getName() + "这本书值得每一个开发者反复品读" + ",书的编号是" + javaDiscountBook.getId() + ",售价" + javaDiscountBook.getPrice() + ",京东618活动,打折后只售" + javaDiscountBook.getDiscountPrice());
}
第一行代码是向上转型,即父类的引用指向了子类对象。向上转型后父类引用不能调用子类自己的方法,所以,需要向下转型,才能调用打折后的方法。
第二行就是子类向下转型。
基本上开闭原则就简单的实现了,如果需要更深层次的理解,还需要多看书,多看源码,多动手。
程序员,年二十有三,头秃,始从文,连考而不中。遂习武,练武场上发一矢,中鼓吏,逐之出。改学IT,自撰一函数,用之,堆栈溢出。