LSP原则

含义:只要父类能出现的地方子类就可以出现,而且替换为子类也不会产生任何错误或异常,使用者可能根本就不需要知道是父类还是子类。但是,有子类出现的地方,父类未必就能适应。

*子类型可以增加方法,但不可删

* 子类必须完全实现父类的方法,在类中调用其他类时务必要使用父类或接口,如果不能使用父类或接口,则说明类的设计已经违背了里氏替换原则。

*子类型中重写的方法必须有相同或子类型的返回值

*子类型中重写的方法必须使用同样类型的参数

*子类型中重写的方法不能抛出额外的异常

同时,这也可以体现在方法的规约上面。

Same or stronger invariants 更强的不变量
Same or weaker preconditions 更弱的前置条件

Same or stronger postconditions 更强的后置条件

采用里氏替换原则的目的就是增强程序的健壮性,版本升级是也可以保持非常好的兼容性。即使增加子类,原有的子类还可以继续运行。在实际项目中,每个子类对应不同的业务含义,使用父类作为参数,传递不同的子类完成不同的业务逻辑。

同时,可以从这里面引申出协变和反协变。

若子类型方法的返回值是父类型的子类,那么它就是协变的。例如:

LSP原则_第1张图片

子类S的方法a返回的是String类型的,而父类是Object类型的。显然,String类型是Object类的子类。所以这是一个协变。

再来看一个异常类的协变:

LSP原则_第2张图片

这就告诉我们,实现协变是要让子类的方法返回值要比父类的类型要低,同时,子类型的异常也是一样的。子类型的异常要更具体才能实现协变。

再来看一个反协变:

LSP原则_第3张图片

反协变是子类的参数的类型比父类参数的类型还要高了,而在java中,这种方式是不被允许的。

你可能感兴趣的:(LSP原则)