Thinking and explaining inheritance in OO
- Inheritance contains the implication that all methods implemented in the parent class are in effect creating specifications and contracts. Although it does not force all subclasses to follow these contracts, if the subclass arbitrarily modifies the implemented methods, it will break the inheritance system.
- Inheritance brings convenience to program design as well as disadvantages. For example, using inheritance will bring invasion to the program, reduce the portability of the program and increase the coupling between objects. If a class is inherited by other classes, when the class needs to be modified, all subclasses must be considered, and after the parent class is modified, all functions involving subclasses may fail
Question posed: how to use inheritance correctly in programming (Richter substitution principle)?
Basic introduction
- The Liskov Substitution Principle was coined in 1988 by a woman named Lee at MIT.
- If for every object O1 of type T1 there is an object O2 of type T2, such that the behavior of all programs P defined by T1 does not change when all objects O1 are substituted for O2, then type T2 is a subclass of type T1. In other words, all references to a base class must transparently use its subclass objects.
- When using inheritance, follow the Richter’s substitution principle and try not to override the methods of the parent class in a subclass
- Richter’s substitution principle tells us that inheritance actually makes two classes more coupled, and can be solved by aggregation, composition, and dependency, where appropriate
Examples of application
package com.braveway.principle.liskov; public class Liskov { public static void main(String[] args) { A a = new A(); System. The out. Println (" 11-3 = "+ a.f unc1 (11, 3)); System. The out. Println (" 1-8 = "+ a.f unc1 (1, 8)); System.out.println("------------"); B b = new B(); System.out.println("11-3="+b.func1(11, 3)); / / here is meant to find the 11-3 System. Out. The println (" 1-8 = "+ b. unc1 (1, 8)); //1-8 System.out.println("11+3+9="+b.func2(11, 3)); Public int func1(int num1,int num2) {return num1-num2; }} // class B inherits A // add A new function: Public int func1(int A,int B) {return A + B; public int func1(int A,int B) {return A + B; } public int func2(int a,int b) { return func1(a,b)+9; }}Copy the code
The solution
- We found an error in the subtraction that used to work well. Class B inadvertently overrides the parent class’s methods, causing the original functionality to fail. In practical programming, we often override the methods of the parent class to accomplish the new function, which is simple to write, but the overall inheritance system will be less reusable. Especially if you’re running a lot of polymorphism.
- The general approach is: the original parent class and child class inherit a more popular base class, the original inheritance relationship removed, there is dependency, aggregation, composition and other relations
Examples of application
package com.braveway.principle.liskov.improve; public class Liskov { public static void main(String[] args) { A a = new A(); System.out.println("11-3="+a.func1(11, 3)); System.out.println("1-8="+a.func1(1, 8)); System.out.println("-------------"); B b = new B(); System.out.println("11+3="+ b.unc1 (11, 3)); / / here is meant to find the 11 + 3 System. Out. The println (" 1 + 8 = "+ b. unc1 (1, 8)); //1+8 System.out.println("11+3+9="+b.func2(11, 3)); System.out.println("11-3="+ b.unc3 (11, 3)); system.out. println("11-3="+ b.unc3 (11, 3)); Class A extends Base{// Returns the difference between two numbers public int func1(int num1,int num2) { return num1-num2; Class B extends Base{private A A = new A(); private A A = new A(); Public int func1(int A,int b) {return A +b; } public int func2(int a,int b) { return func1(a,b)+9; } public int func3(int A,int b) {return this.a.func1(A, b); }}Copy the code