一.定义
里氏替换原则(Liskov Substitution Principle,简写LSP),其实就是继承,子承父业
有两点
1.if foreach object o1 of type S there is Object o2 of type T such that for all programs P defined in terms of T, the behavior of P unchanged when o1 is substituted for o2 then S is 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 user objects of derived classes without knowing it.
翻译:所有引用基类的地方必须能够透明的使用其子类地方,也就是说父亲出现的地方,儿子一定可以出现
二.示例
情景:父亲是个木匠:会做 桌子 椅子 柜子 床,儿子以后是子承父业嘛,也要会这些,当然,青出于蓝而胜于蓝,儿子还会做可飞的木鸟,可懂的木汽车
1 public class Parent { 2 private String name; 3 4 public Parent(String name) { 5 this.name = name; 6 System.out.println(name); 7 } 8 9 public void makeDesk(){ 10 System.out.println("打造红木八仙桌"); 11 } 12 public void makeChair(){ 13 System.out.println("打造红木太师椅"); 14 } 15 public void makeBed(){ 16 System.out.println("打造红木床"); 17 } 18 public void makeCabinet(){ 19 System.out.println("打造红木橱柜"); 20 } 21 } 22 23 24 public class Child extends Parent { 25 public Child(String name) { 26 super(name); 27 } 28 29 public void makeBird(){ 30 System.out.println("打造鲁班鸟"); 31 } 32 } 33 34 public static void main(String[] args) { 35 System.out.println("============父亲打造家具养家==============="); 36 Parent parent = new Parent("父亲"); 37 parent.makeBed(); 38 parent.makeCabinet(); 39 parent.makeChair(); 40 parent.makeDesk(); 41 System.out.println("============儿子长大了也打造家具养家==============="); 42 Child child = new Child("儿子"); 43 child.makeBed(); 44 child.makeCabinet(); 45 child.makeChair(); 46 child.makeDesk(); 47 System.out.println("=================儿子还会学会了鲁班鸟======================="); 48 child.makeBird(); 49 }
打印结果:父亲会的儿子都继承了都会了
三总结
里氏替换原则就是继承
继承的优点:
1.代码共享,减少创建类的工作量,每个子类都拥有父类的方法和属性
2.提高代码的重用性
3.子类可以形似父类但又易于父类,龙生龙,凤生凤,老鼠生来会打洞”是说子拥有父的“种”,“世界上没有两片完全相同的叶子”是指明子与父的不同;
4.提高代码的扩展性,实现父类的方法就可以为所欲为了,很多开源框架的扩展接口都是通过继承父类来完成的
5.提高产品或者项目的开放性
缺点
1.继承是侵入性的。只要继承 就必须拥有父类的所有方法和属性
2.降低了代码的灵活性。子类必须拥有父类的所有方法和属性,让子类自由的世界多了写约束
3.增强了耦合性,当父类的常量、变量和方法被修改时,需要考虑子类的修改,而且在缺乏规范的环境下,这种修改可能带来非常糟糕的结果————大段的代码需要重构。
当然,如果子类不能完整的实现父类的方法,或者父类方法在子类已经发生“畸变”,建议断开继承关系,采用依赖、聚集、组合等关系代替继承。
里氏替换原则为继承定义了良好的规范:
1.子类必须完全实现父类的所有方法
2.子类可以有自己的个性
3.子类重载父类方法时,方法的形参要比父类的宽,宽指的重载时类型可以变大如:父类是HashMap 子类用Map类型,当然也可以是其他类型
4.重写方法的输出结果也就是返回值可以缩小,就是说子类的方法会回执 必须小于等于父类的返回值范围
比如:父类的发你值是T ,子类返回值必须满足 ? extends T 或者 T类型或者 ?implements T