里氏替换原则的简单理解
没用的:
第一种定义, 也是最正宗的定义: 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.
第二种定义: Functions that use pointers or references to base classes must be able to use
objects of derived classes without knowing it.
第二个定义是最清晰明确的, 通俗点讲, 只要父类能出现的地方子类就可以出现, 而且
替换为子类也不会产生任何错误或异常, 使用者可能根本就不需要知道是父类还是子类。 但
是, 反过来就不行了, 有子类出现的地方, 父类未必就能适应。
其实这个简单理解可以理解为 : 有个杀手类,杀手类有个字段是枪(枪类),有个方法是杀人(调用枪类中的方法:射击)。
有个枪类,这个枪类有个方法是射击。
里氏替换原则就是你可以弄一堆 步枪类,手枪类,狙击枪类。然后把它们赋给【杀手类】中的字段(枪类),请注意: 杀手类 需要的是 枪类 。
这时候就可以让步枪类,手枪类,狙击枪类继承于枪类,并且都有与父类相同的方法与属性。这样就可以把这些枪给杀手了,而抢手拿着这些枪就能完成他的任务。
这就是里氏替换原则。
效果:用着父类的时候,搞个子类过去,代码顺畅运行。
1.子类的参数可以扩大,但不能缩小,不然覆写变成了重载,容易引起不容易调试出来的业务混乱。
2.子类的返回可以缩小,但不可以方法通航()
------------------------------------
那什么算是违反里氏替换原则呢?
1、你搞个模型枪,也继承与枪类,然后把它赋给杀手。杀手在杀人时,没有办法射击。这就相当于破坏了里氏替换原则。因为子类【模型枪】没有完整的完成父类【枪类】的功能。
2、假设父类【枪类】还有其他方法:换子弹,扔出去砸人,那么步枪类,手枪类,狙击枪类也必须提供这些方法。如果没有提供也就相当于破坏了。
---------------------
总结: 程序设计过程中如果子类有必要拥有父类的所有方法。那就继承父类,如果有些方法用得到,有些方法用不到,那就别继承了
在项目中, 采用里氏替换原则时, 尽量避免子类的“个性”, 一旦子类有“个性”, 这个子类和父类之间的关系就很难调和了, 把子类当做父类使用, 子类的“个性”被抹杀——委屈了点; 把子类单独作为一个业务来使用, 则会让代码间的耦合关系变得扑朔迷离——缺乏类替换的标准
这些是再看设计模式之禅看到的