“This is the 23rd day of my participation in the August Gwen Challenge.

1. Diction in Diction by Liskov Substitution Principle

I. Definition of Richter’s substitution principle

Richter’s substitution principle means that if for every object O1 of type T1, there is object O2 of type T2, such that the behavior of all programs P defined by T1 does not change when all objects O1 is replaced by O2, then type T2 is a subtype of type T1.

Simply put, you must continue to ensure that the properties of the superclass are still true in the subclasses.

A subclass must implement an abstract method of the parent class, but may not override a nonabstract (implemented) method of the parent class. Subclasses can add their own special methods. When a subclass overrides a method of its parent class, the method’s preconditions (that is, its parameters) are looser than the input parameters of the parent method. When a subclass’s method implements an abstract method of the parent class, the method’s postcondition (that is, the method’s return value) is stricter than the parent class’s.

(2) Advantages of Richter’s substitution principle

(1) Richter’s substitution principle is one of the important ways to realize the open-close principle.

(2) It overcomes the disadvantage of reusability deterioration caused by overwriting the parent class in inheritance.

(3) It is the guarantee of the correctness of the action. That is, class extensions do not introduce new errors into existing systems, reducing the likelihood of code errors.

(III) Case code

1. Situations that do not conform to Richter’s substitution principle

Rectangular class:

public class Rectangle {
    private long width;
    private long height;

    public long getWidth(a) {
        return width;
    }

    public void setWidth(long width) {
        this.width = width;
    }

    public long getHeight(a) {
        return height;
    }

    public void setHeight(long height) {
        this.height = height; }}Copy the code

Square class: inherits rectangles and changes the methods of rectangles

public class Squre extends Rectangle {
    private long length;

    public long getLength(a) {
        return length;
    }

    public void setLength(long length) {
        this.length = length;
    }

    @Override
    public long getWidth(a) {
        return length;
    }

    @Override
    public void setWidth(long width) {
        setLength(width);
    }

    @Override
    public long getHeight(a) {
        return length;
    }

    @Override
    public void setHeight(long height) { setLength(height); }}Copy the code

Error: Check if the length of the rectangle is greater than the width, if not, increment by 1 until the rectangle is larger than the width, but since the square is a subclass of the rectangle, the class passing the square is still valid, but the method execution is in an infinite loop because the length and width are always equal.

public class Check {
    public void resize(Rectangle rectangle){
        while(rectangle.getWidth()>=rectangle.getHeight()){
            rectangle.setHeight(rectangle.getHeight()+1);
            System.out.println("Long"+rectangle.getHeight()+"Wide"+rectangle.getWidth());
        }
        System.out.println("Long"+rectangle.getHeight()+"Wide"+rectangle.getWidth());
    }

    public static void main(String[] args) {
        Squre squre = new Squre();
        squre.setLength(10);
        Check check = newCheck(); check.resize(squre); }}Copy the code

2. The difference of the scope of preconditions of the method of Richter’s substitution principle

When a subclass overrides a method of its parent class, the method’s preconditions (that is, its parameters) are looser than the input parameters of the parent method. You can verify it yourself by writing code

You’ll find that the execution result is still superclass, but once you have more stringent preconditions than the superclass method it’s equivalent to the subclass method, executing a different method. A subclass may extend a method but may not override or override an already implemented method

When a subclass’s method implements an abstract method of the parent class, the method’s postcondition (that is, the method’s return value) is stricter than the parent class’s. This is something that when you implement it in code if you don’t meet this condition the compiler will give you an error.

public class Parent {
    public void method(HashMap hashMap){
        System.out.println("Superclass method execution"); }}public class Son extends Parent{
    public void method(Map hashMap) {
        System.out.println("Subclass method execution");
    }

    public static void main(String[] args) {
        Son son = new Son();
        HashMap hashMap = newHashMap(); son.method(hashMap); }}Copy the code

Composite&Aggregate Reuse Principle

(1) Definition of synthetic reuse principle

The principle of composite reuse refers to the use of object combination (HAS-A)/aggregation (Contanis-a) rather than inheritance relationship to achieve the purpose of software reuse, which can make the system more flexible, reduce the degree of coupling between classes, and the change of one class has less impact on other classes.

Inheritance is called white-box reuse and exposes all the details to subclasses. Composition/aggregation is called black box reuse, and details cannot be obtained for objects outside the class.

(2) Advantages of synthetic reuse principle

(1) It maintains class encapsulation. Because the internal details of component objects are invisible to the new object, this reuse is also known as “black box” reuse.

(2) The coupling degree between the old and new classes is low. This reuse requires fewer dependencies, and the only way a new object can access a component object is through its interface.

(3) High flexibility of reuse. This reuse can occur dynamically at run time, with new objects dynamically referencing objects of the same type as component objects.

(III) Case code

public interface DBconnect {
    String getConnect(a);
}
public class MysqlConnect implements DBconnect {
    public String getConnect(a) {
        return "Mysql connection"; }}public class ProductConnect {
    private DBconnect dBconnect ;

    public void setdBconnect(DBconnect dBconnect) {
        this.dBconnect = dBconnect;
    }

    public void addConnect(a){
        System.out.println(dBconnect.getConnect());
    }

    public static void main(String[] args) {
        ProductConnect productConnect = new ProductConnect();
        productConnect.setdBconnect(newMysqlConnect()); productConnect.addConnect(); }}Copy the code