天天看点

设计模式: 七大原则之 里氏替换原则

七大原则之 里氏替换原则

  • 里氏替换原则:
任何能使用父类对象的地方,都应该能透明的替换为子类对象
		也就说,子类对象可以随时随地替换父类对象,且替换完以后, 语法不会报错,业务逻辑也不会出现问题!
           

反例(正方形不是长方形):

  • 当长方形的的长和宽相等时,就是一个特殊的长方形即正方形
  • 继承的作用:
1. 提高代码饿的重用性
    	2. 多态的前提
           
  • 以前

    两个类能不能发生继承关系的依据
主要看有没有"is a" 关系
           
  • 现在

    两个类能不能发生继承的关系
a. 主要看有没有"is a" 关系
    	b. 在两个类有了is a关系之后,还要考虑子类对象在替换了父类对象之后,业务逻辑是否变化,如果变化,则不能发生继承关系
           
  • 正方形和长方形有"is a" 关系, 那么我们能不能让正方形类就直接去继承长方形类呢?现在不能了!!
  • 为什么呢? 因为还要考虑业务场景,看看在特定的业务场景下,正方形能替换了长方形以后,业务逻辑是否变化
  1. 长方形
//长方形
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 +
                '}';
    }
}
           
  1. 正方形继承长方形
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. 工具类循环让宽累加直到大于高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());
        }
    }
}
           
  1. 测试
    • 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);
    }
}
           
设计模式: 七大原则之 里氏替换原则
  1. 替换成子类对象(多态) 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;
    }
}
           

继续阅读