设计模式之-里氏替换原则LSP

通俗的定义:子类可以扩展父类的功能,但不能改变父类原有的功能

子类可以实现父类的抽象方法,但是不能覆盖父类的非抽象方法。

为什么这么说呢?先看看违背的话会出现什么情况:

新建一个父类Father,里面一个doSomething(int a,int b)方法

1
2
3
public int doSomething(int a, int b) {
return a + b;
}

新建一个子类Son继承Father类,里面同样写一个doSomething(int a,int b)方法,这里我们将父类方法进行重写

1
2
3
public int doSomething(int a, int b) {
return a * b;
}

新建一个Client类,用来测试代码

1
2
3
4
public static void main(String[] args) {
Son son = new Son();
System.out.println(son.doSomething(3,1));
}

可以看到控制台打出‘3’,因为执行的是子类的方法,他重写了父类的doSomething方法,也许你系统正好要使用的就是a-b的功能,而你却输出了a乘b的功能,这样对系统造成潜在风险,如果一定要有a*b整个功能,可以看下面一条,直接子类中增加自己特有的方法即可。

子类中可以增加自己特有的方法。

这个就不需要再说明了

当子类覆盖或实现父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松。

这里同样用代码说明,如果违背会怎么样:

新建一个父类Father,里面一个doSomething(Map m)方法

1
2
3
public void doSomething(Map m) {
System.out.println("父类方法");
}

新建一个子类Son继承Father类,里面同样写一个doSomething(HashMap m)方法,注意这里可不是重写哦,它们参数不一样,所以为重载

1
2
3
 public int doSomething(HashMap m) {
System.out.println("子类方法");
}

新建一个Client类,用来测试代码

1
2
3
4
public static void main(String[] args) {
Son son = new Son();
son.doSomething(new HashMap());
}

可以看到控制台打出‘子类方法’,这里会出现很大问题,问题在于子类并没有去重写父类的doSomething方法,但是却调用的是子类这个方法,因此同样会对于系统造成潜在风险

当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格。

这里也不需要过多说了,子类的返回类型必须小于或等于父类抽象方法的返回类型

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×