Current location - Quotes Website - Signature design - Image Understanding of Li Xite's Substitution Principle
Image Understanding of Li Xite's Substitution Principle
Let's study the essence of LSP. When learning OO, we know that an object is a combination of a set of states and a series of behaviors. State is the internal feature of an object, and behavior is the external feature of an object. LSP expresses that objects in the same inheritance system should have the same behavior characteristics.

At this point, the essential difference between OO inheritance and inheritance in daily life is explained. For example, penguins are classified as birds in the biological classification system. We imitate this system and design such classes and relationships.

There is a method fly in the "bird" class, and penguins naturally inherit this method, but penguins can't fly, so we cover the fly method in the penguin class and tell the caller that penguins can't fly. This is perfectly reasonable. However, this violates LSP. Penguins are a subclass of birds, but penguins can't fly! It should be noted that the "bird" here is no longer a biological bird, but a class and abstraction in software.

Some people will say that it is normal for penguins not to fly, so the code written in this way can also be compiled normally, just add a judgment to the customer code that uses this class. But that's the problem! First of all, the client code and Penguin code are probably not designed at the same time. In today's software outsourcing development mode, you don't even know where the origin of the two modules is, let alone modify the client code. Client programs may be part of legacy systems and may no longer be maintained. If you have to modify the client code because of designing such a "penguin", who should bear the responsibility? Maybe it's God, who told him penguins can't fly. _) "Modify customer code" directly violates OCP, which is the importance of OCP. Violation of LSP will make the existing design unable to be closed!

The modified design is as follows:

But is this all about LSP? The book gives a classic example, another unreasonable example: a square is not a rectangle. The details of this paradox can be found on the Internet, so I won't talk much nonsense.

LSP does not provide a solution to this problem, but only raises such a problem.

Therefore, engineers began to pay attention to how to ensure the behavior of the object. 1988, B. Meyer put forward the theory of Design by Contract. DbC borrows a set of methods from formal methods to ensure object behavior and its own state. Its basic concept is simple:

Prerequisites:

Before calling each method, the method should check the correctness of the passed-in parameters, and the correct method can be executed. Otherwise, it is considered that the caller has violated the agreement and will not execute it. This is called a prerequisite.

Postcondition:

Once the precondition is checked, the method must be executed, and the execution result must conform to the contract. This is the so-called postcondition.

Constant:

The object itself has a set of inspection conditions to check its own state to ensure that the essence of the object remains unchanged, which is called invariance.

These are the constraints of a single object. In order to satisfy LSP, when there is inheritance relationship, the preconditions of methods in subclasses must be the same as or more relaxed than those of methods covered in superclasses; The postconditions of methods in subclasses must be the same as or stricter than those of methods in superclasses.

Some features in OO language can illustrate this problem:

When inheriting and rewriting superclass methods, the visibility of methods in subclasses must be equal to or greater than that of methods in superclass, and the detected exceptions thrown by methods in subclasses can only be subclasses of detected exceptions thrown by corresponding methods in superclass.

Public class superclass {

The public void method a () threw an exception {}

}

Common class subclass extended superclass (

//This rewriting is illegal.

Private void method a () throws IOException{}

}

Public class SubClassB extended superclass (

//This override is possible.

Public void methodA () throws FileNotFoundException{}

}

Starting from Java5, the return value of a method in a subclass can also be a subclass corresponding to the return value of a superclass method. This is called "covariation"

Public class superclass {

WeChat official account calculation () {

Returns null

}

}

Common class subclass extended superclass (

//It can only be compiled in Java 5 or later.

Common integer calculation () {

Returns null

}

}

It can be seen that all these characteristics follow LSP well. But what about DbC? Unfortunately, mainstream object-oriented languages (whether dynamic or static) have not increased their support for DbC. But with the appearance of AOP concept, I believe DbC will soon become one of the important features of OO language.

Some digressions:

A while ago, two articles, "Ring the bell in the OO era" and "For whom the bell tolls", attracted numerous discussions. It mentioned many shortcomings of OO language. In fact, according to LSP and OCP, both static and dynamic systems should have strict constraints on the behavior of objects as long as they are OO designed. This constraint is not only reflected in the method signature, but also in the specific behavior itself. This is the true meaning of LSP and DbC. From this point of view, we can't explain the advantages and disadvantages of the dynamic language of "Everything is an object" and the interface programming language of "C++, Java", both of which need to be improved. Brother Zhuang's DJ idea has begun to introduce the concept of DbC. This is still worth looking forward to. ^_^

In addition, the semantics of interfaces are constantly being strengthened by concepts such as OCP, LSP and DbC, and interfaces express the "contractual" relationship between object behaviors. Rather than simply as a grammatical sugar to achieve multiple inheritance.