设计模式六原则 - 里氏替换原则

里氏替换原则(Liskov Substitution Principle, LSP)

所有引用基类(父类)的地方必须能透明地使用其子类的对象。(子类可以扩展父类的功能,但不能改变父类原有的功能)

注意

  • 里氏代换原则是实现开闭原则的重要方式之一

  • 在程序中尽量使用基类类型对对象进行定义,而在运行时再确定其子类型,用子类来替换父类。

  • 最好将父类定义为抽象类或者接口,让子类去继承或者实现。运行时,子类实例替换父类实例,如果添加新功能,就新加一个子类。

  • Java 编译阶段中,Java 编辑器会检查一个程序是否符合里氏替换原则,这是一个与实现无关的、语意上的检查

  • 尽量不去重载和重写父类的方法

  • 传递参数时使用基类对象,除此以外,在定义成员变量、定义局部变量、确定方法返回类型时都可使用里氏代换原则。针对基类编程,在程序运行时再确定具体子类。

继承带来的风险

1
2
3
4
5
public class A {
public int fun1(int a , int b){
return a - b;
}
}
1
2
3
4
5
6
7
8
9
public class B extends A{
public int func1(int a, int b){
return a+b;
}

public int func2(int a, int b){
return func1(a,b)+100;
}
}
1
2
3
4
5
6
7
8
9
public class Main {
public static void main(String[] args){
// 因为不小心重写了父类的fun1方法,导致原本正常的相减功能异常
B b = new B();
System.out.println("100-50="+b.func1(100, 50));
System.out.println("100-80="+b.func1(100, 80));
System.out.println("100+20+100="+b.func2(100, 20));
}
}

继承包含这样一层含义:父类中凡是已经实现好的方法(相对于抽象方法而言),实际上是在设定一系列的规范和契约,虽然它不强制要求所有的子类必须遵从这些契约,但是如果子类对这些非抽象方法任意修改,就会对整个继承体系造成破坏。而里氏替换原则就是表达了这一层含义.

六大设计原则:

当前网速较慢或者你使用的浏览器不支持博客特定功能,请尝试刷新或换用Chrome、Firefox等现代浏览器