七大原则之 里氏替换原则
- 里氏替换原则:
任何能使用父类对象的地方,都应该能透明的替换为子类对象
也就说,子类对象可以随时随地替换父类对象,且替换完以后, 语法不会报错,业务逻辑也不会出现问题!
反例(正方形不是长方形):
- 当长方形的的长和宽相等时,就是一个特殊的长方形即正方形
- 继承的作用:
1. 提高代码饿的重用性
2. 多态的前提
以前
两个类能不能发生继承关系的依据
主要看有没有"is a" 关系
现在
两个类能不能发生继承的关系
a. 主要看有没有"is a" 关系
b. 在两个类有了is a关系之后,还要考虑子类对象在替换了父类对象之后,业务逻辑是否变化,如果变化,则不能发生继承关系
- 正方形和长方形有"is a" 关系, 那么我们能不能让正方形类就直接去继承长方形类呢?现在不能了!!
- 为什么呢? 因为还要考虑业务场景,看看在特定的业务场景下,正方形能替换了长方形以后,业务逻辑是否变化
- 长方形
//长方形
class Rectangle {
private double length; //长
private double width; //宽
public double getLength() {
return length;
}
public void setLength(double length) {
this.length = length;
}
public double getWidth() {
return width;
}
public void setWidth(double width) {
this.width = width;
}
@Override
public String toString() {
return "Rectangle{" +
"length=" + length +
", width=" + width +
'}';
}
}
- 正方形继承长方形
class Square extends Rectangle {
private double sidelength;
@Override
public double getLength() {
return sidelength;
}
@Override
public void setLength(double length) {
this.sidelength = length;
}
@Override
public double getWidth() {
return sidelength;
}
@Override
public void setWidth(double width) {
this.sidelength = width;
}
}
- 工具类循环让宽累加直到大于高1
class Utils {
public static void transform(Rectangle r) {
while (r.getWidth() <= r.getLength()) {
r.setWidth(r.getWidth() + 1);
System.out.println(r.getWidth()+":"+r.getLength());
}
}
}
- 测试
- Rectangle r = new Rectangle ();
public class AppTest {
public static void main(String[] args) {
Rectangle r = new Rectangle ();
r.setWidth(12);
r.setLength(20);
Utils.transform(r);
}
}
- 替换成子类对象(多态) Rectangle r = new Square();
public class AppTest {
public static void main(String[] args) {
Rectangle r = new Square();
r.setWidth(12);
r.setLength(20);
Utils.transform(r);
}
}
此时业务逻辑出现了问题, 我们原本只要循环到宽大于高1,但是更改为子类后,确变成了死循环
所有说正方形不是长方形.
正例:
- 只需要把正方形不要继承长方形即可
class Square {
private double sidelength;
public double getLength() {
return sidelength;
}
public void setLength(double length) {
this.sidelength = length;
}
public double getWidth() {
return sidelength;
}
public void setWidth(double width) {
this.sidelength = width;
}
}