LSP(Liskov Subsitution Principle)提供了一个原则去评价继承的合理性.
一般情况下, 当我们发现A “IS-A” B 的时候, 我们会让B继承A.
但是LSP告诉我们, 只有当A “IS-SUBSTITUTABLE-FOR” B的时候, 才应该让B继承A, 否则会带来一些问题.
例子
假设有一个类Rectangle
, 他有长和宽两个属性, 那么Square
是否应该是Rectangle
的一个子类呢?
关键就是看他们是否满足"IS-SUBSTITUTABLE-FOR" 的关系.
Rectangle
默认他的长和宽是独立变化的, 在这种前提下, 是不可能将Rectangle
替换为Square
的, 所以他们不应该是继承关系.
坏味道
对接口的不完全实现
当实现一个接口的时候, 你发现有些方法用不上, 于是就返回一个NotImplementedException
. 这时你其实就违反了LSP.
循环中判断类型
假设你对一个类的实例列表进行循环, 当你不得不在里面加上一个判断条件在类型为某一个子类的时候要特殊处理, 这时候也违反了LSP.
违反LSP的坏处
- 随着程序的增长, 代码中会出现大量的逻辑判断.
- 无法暴露接口给其他开发者, 无法合作, 无法发布.
Reference
https://deviq.com/liskov-substitution-principle/