里氏替换原则

关于里氏替换原则(Liskov Substitution Principle, LSP)的定义:
第一种

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.
(如果对每个类型为S的对象o1都有类型为T的对象o2,使得以T定义的所有程序P中,将所有的对象o2都替换为o1时,程序P的行为没有发生变化,那么类型S是类型T的子类型)

(如果对程序P中定义的所有类型为T的对象02,都用S类型的对象01替换,程序的行为没有发生变化,那么S为T的子类)

S o1 = new S();    => T o2 = new T();
o1.do();

即子类替换父类,程序运行未发生变化
第二种

functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it. (所有引用基类的地方必须能透明地使用其子类的对象)

里氏替换原则包含的几种含义:
1、子类必须完全实现父类的方法
eg:

public abstract class AbstractGun{
  public abstract void shoot();
}
public class Rifle extends AbstractGun{
  public void shoot(){
    System.out.println("XX shoot");
}
}
//使用上 
public class Solider {
  private AbstractGun gun;

  public void SetGun(AbstractGun _gun){
    this.gun = _gun;
}
  public void kill()
{
    gun.shoot();
}
}

在类中调用其他类时,务必要使用父类 或接口,如果不能使用父类或接口,则说明类的设计已经违背了 里氏替换原则

如果 子类不能完整的实现父类的方法,或者父类的某些方法已经在子类中发生畸变,建议断开继承关系,采用 依赖、聚集、组合等关系代替继承。
2、子类可以有自己的个性

子类可以有自己的方法和属性,因为 里氏替换原则可以正着用(子类型替换父类型),但是不能反过来用。即 向下转型(downcast)是不安全的
3、覆盖或实现父类方法时输入参数可以被放大

子类替换父类时,在没有覆写要求子类相关的方法永远不会被执行,这算是也是里氏替换原则的特点吧。
4、覆写或实现父类方法时输出结果可被缩小

覆写的要求 要覆写的方法,子类中方法的返回类型应小于父类的返回值类型
重载则要求方法的输入类型个数量不相同
采用里氏替换原则的目的就是增强程序的健壮性 及时有相应的扩展也能很好的使用。

总结一下:
关于里氏替换原则可以认为是完美诠释了继承的特点,子类就是用来扩展的,重载或者覆写,向上转型或者向下转型,只要子类的定义合理的诠释扩展都是可以应用替换原则的,也是这个原则的基本要求。

你可能感兴趣的:(里氏替换原则)