最简单直接地理解Java软件设计原则之里氏替换原则

理论性知识学习

定义

里氏替换原则,Liskov Substitution principle(LSP)。测试

抽象定义是下面这样的设计

若是对每个类型为T1的对象O1,都有类型为T2的对象O2,使得以T1定义的全部程序P在全部的对象O1都替换成O2时,程序P的行为没有发生变化,那么类型T2是类型T1的子类型。对象

通俗地解释一下blog

一个软件实体若是适用一个父类的话,那必定适用于其子类,全部引用父类的地方必须能透明地使用其子类的对象,子类对象可以替换父类对象,而程序逻辑不变。继承

引伸一下,若是子类替换父类,还必须保证程序逻辑不变,就必须知足如下几点。ip

  • 子类能够实现父类的抽象方法,但不能覆盖父类的非抽象方法。
  • 子类中能够增长本身特有的方法。
  • 当子类的方法重载父类的方法时,方法的前置条件(即方法的输入,入参)要比父类方法的输入参数更宽松。
  • 当子类的方法实现父类的方法时(重写,重载或实现抽象方法),方法的后置条件(方法的输出,返回值)要比父类更严格或相等。

 优势

增强程序的健壮性,同时变动时能够作到很是好的兼容性。ci

提升程序的维护性,扩展性,下降需求变动时引入的风险。编译器

 

代码实战1it

实现一个正方形继承长方形的场景,由于正方形是一种特殊的长方形。

定义一个长方形,以下图

最简单直接地理解Java软件设计原则之里氏替换原则

 

定义一个正方形,以下图,重写了父类的方法。

最简单直接地理解Java软件设计原则之里氏替换原则

 

最后执行测试方法,当宽大于等于高时,就改变宽和高。以下图

最简单直接地理解Java软件设计原则之里氏替换原则

 

当用子类正方形替换父类时,程序就会进入无限循环,以下图

最简单直接地理解Java软件设计原则之里氏替换原则

 

根据以上得出,子类能够实现父类的抽象方法,但不能覆盖父类的非抽象方法

 

代码实战2

首先定义一个简单的父类,以下图

最简单直接地理解Java软件设计原则之里氏替换原则

 

而后定义一个子类,子类的入参类型Map比父类的入参HashMap宽松,以下图

最简单直接地理解Java软件设计原则之里氏替换原则

 

最后测试以下图

最简单直接地理解Java软件设计原则之里氏替换原则

 

由测试结果能够看出,child类彻底能够替换base类去执行。遵循了里式替换原则,

即当子类的方法重载父类的方法时,方法的前置条件(即方法的输入,入参)要比父类方法的输入参数更宽松。

代码实战3

仍是定义一个简单的父类,方法返回类型为HashMap,以下图

最简单直接地理解Java软件设计原则之里氏替换原则

 

定义一个子类,实现父类抽象方法时,返回值类型为Map,编译器就会直接报错,以下图

最简单直接地理解Java软件设计原则之里氏替换原则

 

根据以上能够得出结论

当子类的方法实现父类的方法时(重写,重载或实现抽象方法),方法的后置条件(方法的输出,返回值)要比父类更严格或相等。

我的总结

一开始学习里式替换原则时,也是不明白。最后也是慢慢理解透的。总结起来就是

子类能够替换父类,替换后,不能改变程序的运行逻辑。

也欢迎你们在评论区留下本身的见解!

相关文章
相关标签/搜索