里氏替换原则(LSP)

起源
继承可以共享代码,提高代码的重用性,可以清醒表达现实中父子关系,通过继承父类提供扩展性,提高开放性。
然鹅,
继承是侵入性的(之类必须拥有父类的所有属性和方法),降低了代码的灵活性(子类有了更多的约束),增加了耦合性。如果设计不好修改父类的话可能会出现大面积的重构。。。
为了让利大于弊,所以引入了LSP。

定义:
1:If for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T,the behavior of P is unchanged when o1 is substituted for o2 then S is a subtype of T.
如果对每一个类型为S的对象o1,都有类型为T的对象o2,使得以T定义的所有程序P在所有对象o1都替换成o2时,程序P的行为没有发生变化,那么S类型是T类型的子类型

2:Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it.
所有引用基类的地方必须能透明地使用其子类对象
很显然第二个定义通俗易懂一点。

咸鱼:所有父类出现的地方都可以换成其对应的子类,且程序可以正常运行不会产生异常或错误,使用者不需要关心是子类还是父类。但是子类出现的地方不能替换为父类。如:List list = new ArrayList();

具体含义:
1:子类必须完全实现父类的方法
方法参数写成父类类型,可以传入具体的子类
2:子类可以有自己特有的方法
子类出现的地方,未必可以使用父类替换
3:重写或现实父类方法时,参数可以被放大
在相同方法名重载test(ArrayList list),父类参数较大(如ArrayList),子类参数较小(如List)时test(List list),传入ArrayList即便子类调用也会执行父类的方法.如果想要执行子类的方法就必须重写父类的方法而不是重载!会优先执行较小的方法,如果子类参数比父类小将引起逻辑混乱。所以,子类中方法的前置条件必须与父类中被重写的方法的前置条件相同或者更宽松。
4:重写或实现父类方法时,输出结果可以被缩小。
方法名相同(重写或重载),子类方法返回的结果类型必须小于父类方法返回的结果类型。
主要增强健壮性和兼容性!

使用里氏替换原则时,应尽量避免子类的“个性”,将子类作为父类使用。否则如果将子类作为一个单独的业务来使用,则会让代码的耦合关系变得混乱,缺乏类替换的标准

更新时间:2020-01-20 22:12:05

本文由 寻非 创作,如果您觉得本文不错,请随意赞赏
采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
原文链接:https://www.zhouning.group/archives/里氏替换原则lsp
最后更新:2020-01-20 22:12:05

评论

Your browser is out of date!

Update your browser to view this website correctly. Update my browser now

×