理论性知识
定义
里氏替换原则,Liskov Substitution principle(LSP)。
抽象定义是下面这样的
如果对每一个类型为T1的对象O1,都有类型为T2的对象O2,使得以T1定义的所有程序P在所有的对象O1都替换成O2时,程序P的行为没有发生变化,那么类型T2是类型T1的子类型。
通俗地解释一下
一个软件实体如果适用一个父类的话,那一定适用于其子类,所有引用父类的地方必须能透明地使用其子类的对象,子类对象能够替换父类对象,而程序逻辑不变。
引申一下,如果子类替换父类,还必须保证程序逻辑不变,就必须满足以下几点。
- 子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法。
- 子类中可以增加自己特有的方法。
- 当子类的方法重载父类的方法时,方法的前置条件(即方法的输入,入参)要比父类方法的输入参数更宽松。
- 当子类的方法实现父类的方法时(重写,重载或实现抽象方法),方法的后置条件(方法的输出,返回值)要比父类更严格或相等。
优点
加强程序的健壮性,同时变更时可以做到非常好的兼容性。
提高程序的维护性,扩展性,降低需求变更时引入的风险。
代码实战1
实现一个正方形继承长方形的场景,因为正方形是一种特殊的长方形。
定义一个长方形,如下图
定义一个正方形,如下图,重写了父类的方法。
最后执行测试方法,当宽大于等于高时,就改变宽和高。如下图
当用子类正方形替换父类时,程序就会进入无限循环,如下图
根据以上得出,子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法
代码实战2
首先定义一个简单的父类,如下图
然后定义一个子类,子类的入参类型Map比父类的入参HashMap宽松,如下图
最后测试如下图
由测试结果可以看出,child类完全可以替换base类去执行。遵循了里式替换原则,
即当子类的方法重载父类的方法时,方法的前置条件(即方法的输入,入参)要比父类方法的输入参数更宽松。
代码实战3
还是定义一个简单的父类,方法返回类型为HashMap,如下图
定义一个子类,实现父类抽象方法时,返回值类型为Map,编译器就会直接报错,如下图
根据以上可以得出结论
当子类的方法实现父类的方法时(重写,重载或实现抽象方法),方法的后置条件(方法的输出,返回值)要比父类更严格或相等。
个人总结
一开始学习里式替换原则时,也是不明白。最后也是慢慢理解透的。总结起来就是
子类可以替换父类,替换后,不能改变程序的运行逻辑。
也欢迎大家在评论区留下自己的看法!
原文转载:http://www.shaoqun.com/a/522476.html
全球速卖通:https://www.ikjzd.com/w/81
xinong:https://www.ikjzd.com/w/1368
理论性知识定义里氏替换原则,LiskovSubstitutionprinciple(LSP)。抽象定义是下面这样的如果对每一个类型为T1的对象O1,都有类型为T2的对象O2,使得以T1定义的所有程序P在所有的对象O1都替换成O2时,程序P的行为没有发生变化,那么类型T2是类型T1的子类型。通俗地解释一下一个软件实体如果适用一个父类的话,那一定适用于其子类,所有引用父类的地方必须能透明地使用其子类的
赛兔:赛兔
google趋势:google趋势
年终总结写了吗?让你年终总结变得高大上的方法来了!:年终总结写了吗?让你年终总结变得高大上的方法来了!
抖音红人牛肉哥1亿入股洋码头成为合伙人:抖音红人牛肉哥1亿入股洋码头成为合伙人
口述:只有满足爱爱需求 男友才对我好情感第一次处女:口述:只有满足爱爱需求 男友才对我好情感第一次处女
没有评论:
发表评论