Six Design Principles-The Richter Substitution Principle

2. Liskov Substitution Principle (LSP)
definition: All references to the base class must be able to transparently use the subclass object
. The Liskov Substitution Principle : that is, when an object is replaced by his subclass in the program At this time, the program can continue the original behavior, and he cannot detect the difference between the rune and subclasses. But the reverse is not true. If a program uses a subclass, it is not necessarily applicable to the parent class.
Take a computer as an example: a computer has a CPU, a computer is a program entity, a CPU is the base class it uses, and a CPU has a subclass IntelCpu.
public class Cpu {

    public void work(){
        System.out.println("CPU在工作");
    }
}
public class IntelCpu extends Cpu {
    @Override
    public void work() {
        System.out.println("英特尔CPU工作");
    }
}
public class Computer {

    private Cpu cpu;

    public void run() {
        this.cpu.work();
    }

    public Cpu getCpu() {
        return cpu;
    }

    public void setCpu(Cpu cpu) {
        this.cpu = cpu;
    }
}
The computer depends on the parent class. At this time, the CPU is replaced with the Intel type, and the computer can still work normally. It does not notice any changes, which is in line with the Liskov substitution principle.  
And conversely, suppose there is a computer now, it can only work with IntelCpu.
public class IntelCpuComputer {
    private IntelCpu cpu;
    
    public void run() {
        this.cpu.work();
    }

    public IntelCpu getCpu() {
        return cpu;
    }

    public void setCpu(IntelCpu cpu) {
        this.cpu = cpu;
    }
}
If you replace IntelCpu with the parent CPU at this time, the computer will not work properly because it can only work properly when using IntelCpu.
public static void main(String[] args) {
      IntelCpuComputer computer = new IntelCpuComputer();
      computer.setCpu(new Cpu());//报错
  }
As another example, we all know that squares are special rectangles in mathematics. Can we say that squares are a subclass of rectangles?  
We use code to represent squares and rectangles:
/**
 * 长方形
 * @author ZhaoShuai
 * @date Create in 2020/4/12
 **/
public class Rectangle {

    private Integer height;
    private Integer width;

    public Integer getHeight() {
        return height;
    }

    public void setHeight(Integer height) {
        this.height = height;
    }

    public Integer getWidth() {
        return width;
    }

    public void setWidth(Integer width) {
        this.width = width;
    }
}
/**
 * 正方形
 * @author ZhaoShuai
 * @date Create in 2020/4/12
 **/
public class Square {
    
    private Integer side;

    public Integer getSide() {
        return side;
    }

    public void setSide(Integer side) {
        this.side = side;
    }
}
We all know that the parent class is encapsulated by extracting the sub-classes. From the above code, we can see that the structural formula of the rectangle and the square are different. The rectangle has the attributes of length and width, while the square has the attribute of variable length. 
Therefore, squares are not subclasses of rectangles. Of course, it is also possible to force rectangles to inherit as parent classes, but we do not inherit for inheritance. This kind of inheritance for inheritance is not part of the Liskov Substitution Principle.
package com.xiazhi.principle.lsp;

/**
 * @author ZhaoShuai
 * @date Create in 2020/4/12
 **/
public class SquareExtendsRectangle extends Rectangle {

    private Integer side;

    @Override
    public void setHeight(Integer height) {
        this.setSide(height);
    }

    @Override
    public void setWidth(Integer width) {
        this.setSide(width);
    }

    @Override
    public Integer getHeight() {
        return this.getSide();
    }

    @Override
    public Integer getWidth() {
        return this.getSide();
    }

    public Integer getSide() {
        return side;
    }

    public void setSide(Integer side) {
        this.side = side;
    }
}
It can be seen that we forcibly inherited the rectangle from the square, and then we write a test class:
 public static void main(String[] args) {
        System.out.println("============长方形==============");
        Rectangle rectangle = new Rectangle();
        rectangle.setHeight(10);
        rectangle.setWidth(20);
        print(rectangle);

        System.out.println("============正方形==============");
        Rectangle square = new SquareExtendsRectangle();
        square.setHeight(10);
        print(square);

    }

    private static void print(Rectangle rectangle) {
        System.out.println("高:"+rectangle.getHeight());
        System.out.println("宽:" + rectangle.getWidth());
    }
After testing, we found that it seems to be working properly, at this time we add another method:
public static void main(String[] args) {
        System.out.println("============长方形==============");
        Rectangle rectangle = new Rectangle();
        rectangle.setHeight(10);
        rectangle.setWidth(20);
        test(rectangle);

        System.out.println("============正方形==============");
        Rectangle square = new SquareExtendsRectangle();
        square.setHeight(10);
        test(square);

    }

    private static void print(Rectangle rectangle) {
        System.out.println("高:"+rectangle.getHeight());
        System.out.println("宽:" + rectangle.getWidth());
    }

    private static void test(Rectangle rectangle) {
        while (rectangle.getWidth() >= rectangle.getHeight()) {
            rectangle.setHeight(rectangle.getHeight()+1);
            print(rectangle);
        }
    }
After running, you can find that the rectangle can run normally, but the square will have an endless loop, so this is not in line with the Liskov substitution principle. Because the subclass object cannot be used where the parent class is referenced. 
In the design of the class, according to the principle of dependency inversion, it is necessary to use abstract classes or interfaces. If abstract classes or interfaces cannot be used, it means that the design violates the Liskov Substitution Principle (LSP)

Guess you like

Origin www.cnblogs.com/Zs-book1/p/12714021.html