java设计模式-里式替换原则
一:里式替换原则:
(1):里氏替换原则(liskov substitution principle,lsp)由麻省理工学院计算机科学实验室的里斯科夫(liskov)女士在 1987 年的“面向对象技术的高峰会议”(oopsla)上发表的一篇文章《数据抽象和层次》(data abstraction and hierarchy)里提出来的,她提出:继承必须确保超类所拥有的性质在子类中仍然成立(inheritance should ensure that any property proved about supertype objects also holds for subtype objects)。
(2):里氏替换原则主要阐述了有关继承的一些原则,也就是什么时候应该使用继承,什么时候不应该使用继承,以及其中蕴含的原理。里氏替换原是继承复用的基础,它反映了基类与子类之间的关系,是对开闭原则的补充,是对实现抽象化的具体步骤的规范。
二:里式替换原则的作用:
(1):里氏替换原则是实现开闭原则的重要方式之一。
(2):它克服了继承中重写父类造成的可复用性变差的缺点。
(3):它是动作正确性的保证。即类的扩展不会给已有的系统引入新的错误,降低了代码出错的可能性。
(4):加强程序的健壮性,同时变更时可以做到非常好的兼容性,提高程序的维护性、可扩展性,降低需求变更时引入的风险。
三:里式替换原则的定义:
(1):子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法
(2):子类中可以增加自己特有的方法
(3):当子类的方法重载父类的方法时,方法的前置条件(即方法的输入参数)要比父类的方法更宽松
(4):当子类的方法实现父类的方法时(重写/重载或实现抽象方法),方法的后置条件(即方法的的输出/返回值)要比父类的方法更严格或相等
四:代码实现
public class bird { /** * 飞行时速 */ public double fly; public void setfly(double fy){ this.fly=fy; } public double gettime(double road){ return (road/fly); } } class sparrow extends bird{ } class penguin extends bird{ public void setfly(double fy){ fly=0; } } class test{ public static void main(string[] args) { bird bird=new sparrow(); bird bird1=new penguin(); bird.setfly(110); bird1.setfly(110); try{ system.out.println("麻雀飞了"+bird.gettime(200)+"公里"); system.out.println("企鹅飞了"+bird1.gettime(200)+"公里"); }catch (exception e){ system.out.println("出现错误"); } } }
运行结果:
企鹅从科学的角度来说是鸟类动物,但是它不会飞,所以不能定义成鸟类,
此时结果出现了正无穷的错误,因为penguin类违背了里式替换原则,重写了父类的方法,解决方法:取消企鹅原来的继承关系,定义鸟类和企鹅类更一般的父类。
如下图:
企鹅继承了动物类,拥有了跑的方法。
上一篇: 设计模式-访问者模式