LSP原则要求,子类要能替换父类型,从中总结出几点符合的条件要求:
- 子类的Spec要强于或等于父类。Spec强=前置条件更弱 |(在对比双方中满足更强的前置条件下)后置条件更强。
- 子类型的异常可以更具体,协变
- 子类型的返回类型可以更具体,协变
其实这点很好理解,比如父类的返回值原本为Animal,换回子类型之后,返回的是Cat,其中Cat extends Animal,这在编译上是可以通过的。如果父类型是Cat,子类型返回Animal,那这就在编译上无法通过了 - 子类型的参数类型可以更宽松,逆变
同样从编译角度去考虑,假设父类型传入的是一个接口的参数,例如ArrayList<.L>,那么子类型改为List<.L>,原本传入父类型的参数仍然可以传入子类型的对象中,所以是满足的。如果反过来,父类型中是List<.L>,子类型是ArrayList<.L>,那么这在编译上就不能通过了,因为传入父类型的参数可以是LinkList,与ArrayList不同。