The Liskov substitution principle is one of the basic principles of object-oriented design. It advocates using "Abstraction" and "Polymorphism" to change the static structure in the design to a dynamic structure to maintain the stability of the design. Closeness. "Abstraction" is a function provided by the language, and "polymorphism" is achieved by inheritance semantics.
The Liskov Substitution Principle (LSP) was proposed by Ms. Liskov of the MIT Computer Science Laboratory in 1987. It was proposed in an article "Data Abstraction and Hierarchy" published at the "Object-Oriented Technology Summit Conference" (OOPSLA). She proposed that inheritance must ensure that the properties owned by the superclass are in the subclass. Inheritance should ensure that any property proved about supertype objects also holds for subtype objects.
The Liskov substitution principle mainly explains some principles about inheritance, that is, when inheritance should be used, when inheritance should not be used, and the principles contained therein. Liskov substitution is originally the basis for inheritance reuse. It reflects the relationship between base classes and subclasses, supplements the opening and closing principle, and regulates the specific steps to achieve abstraction.
The role of Liskov substitution principle
The main functions of Liskov substitution principle are as follows.
1. The Liskov substitution principle is one of the important ways to realize the opening and closing principle.
2. It overcomes the shortcomings of poor reusability caused by overriding parent classes in inheritance.
3. It is the guarantee of the correctness of the action. That is, the extension of the class will not introduce new errors into the existing system, reducing the possibility of code errors.
How to implement the Liskov substitution principle
The Liskov substitution principle is generally speaking: a subclass can extend the functions of the parent class, but it cannot change the original function of the parent class. function. In other words: when a subclass inherits a parent class, try not to override the parent class's methods except adding new methods to complete new functions.
If you complete new functions by overriding the parent class method, although it is simple to write, the reusability of the entire inheritance system will be relatively poor, especially when polymorphism is used frequently, the program will run The probability of error is very high.
If the program violates the Liskov substitution principle, the object of the inherited class will have a runtime error where the base class appears. At this time, the correction method is: cancel the original inheritance relationship and redesign the relationship between them.
Regarding the example of Liskov substitution principle, the most famous one is "a square is not a rectangle". Of course, there are many similar examples in life. For example, penguins, ostriches and kiwis are classified as birds from a biological perspective; but from a class inheritance relationship, because they cannot inherit the "bird" ability to fly function, so they cannot be defined as subclasses of "bird". Similarly, since "balloon fish" cannot swim, it cannot be defined as a subcategory of "fish"; "toy cannon" cannot blow up enemies, so it cannot be defined as a subcategory of "cannon", etc.
The following uses "a kiwi is not a bird" as an example to illustrate the Richter substitution principle.
[Example 2] Application of Richter substitution principle in the example of "kiwi is not a bird".
Analysis: Birds generally fly. For example, the flying speed of swallows is about 120 kilometers per hour. But New Zealand's kiwis are unable to fly due to degenerated wings. Suppose you want to design an example and calculate the time it takes for these two birds to fly 300 kilometers. Obviously, if you use a swallow to test this code, the result is correct and the required time can be calculated; but if you use a kiwi to test it, the result will be a "divide by zero exception" or "infinity", which is obviously not in line with expectations. The class diagram As shown in Figure 1.
The program code is as follows:
package principle; public class LSPtest { public static void main(String[] args) { Bird bird1=new Swallow(); Bird bird2=new BrownKiwi(); bird1.setSpeed(120); bird2.setSpeed(120); System.out.println("如果飞行300公里:"); try { System.out.println("燕子将飞行"+bird1.getFlyTime(300)+"小时."); System.out.println("几维鸟将飞行"+bird2.getFlyTime(300)+"小时。"); } catch(Exception err) { System.out.println("发生错误了!"); } } } //鸟类 class Bird { double flySpeed; public void setSpeed(double speed) { flySpeed=speed; } public double getFlyTime(double distance) { return(distance/flySpeed); } } //燕子类 class Swallow extends Bird{} //几维鸟类 class BrownKiwi extends Bird { public void setSpeed(double speed) { flySpeed=0; } }
The running results of the program are as follows:
如果飞行300公里: 燕子将飞行2.5小时. 几维鸟将飞行Infinity小时。
The reason for the program running error is: kiwi birds The setSpeed(double speed) method of birds has been overridden, which violates the Liskov substitution principle. The correct approach is to cancel the original inheritance relationship of the kiwi and define a more general parent class of the bird and the kiwi, such as the animal class, both of which have the ability to run. Although the Kiwi's flight speed is 0, its running speed is not 0. You can calculate the time it takes to run 300 kilometers.
The class diagram is shown in Figure 2.
For more related knowledge, please visit: PHP Chinese website!
The above is the detailed content of What is the Richter substitution principle?. For more information, please follow other related articles on the PHP Chinese website!