This is the 31st day of my participation in the August Text Challenge.More challenges in August

Richter’s substitution principle

define

1. In layman’s terms, a subclass extends the functionality of its parent class, but does not change the functionality of its parent class.

2. Replace a superclass object with a subclass object in the program, the program will not generate any errors and exceptions, the reverse is not true.

3. It is one of the important ways to realize the open and close principle. Because the use of base class objects can use subclass objects, the program tries to use the parent class type to define the object, and then establish the subclass type at run time, and replace the parent class object with the subclass object.

The implications of The Richter substitution principle

1. A subclass can implement abstract methods of its parent class, but cannot override non-abstract methods of its parent class.

2. Subclasses can add their own special methods.

3. When a subclass overrides or implements a superclass method, method preconditions (parameters) are looser than those of the superclass method. 4. When a subclass’s method implements the (abstract) method of the parent class, the postcondition (that is, the return value of the method) is stricter than that of the parent class.

The role of inheritance

1. Improve code reuse

2. The premise of polymorphism

Methods to rewrite

The same return value type, method name, and parameter list constitute method rewriting

Two limitations of method rewriting

1. When a subclass overrides a parent class method, its access modifiers cannot be stricter than those of the parent class. example

public class TestExtends {
     public  static void main(String[] args) {
    	 Father f=newFather(); f.method1(); }}class Father{
	public void method1(a){}}class Son extends Father{}Copy the code

Now we’re going to replace the parent object with a subclass object, and that’s fine

public class TestExtends {
     public  static void main(String[] args) {
    	 Father f=newFather(); f.method1(); }}class Father{
	public void method1(a){}}class Son extends Father{}Copy the code

Overrode parent class method1, found an error

Here’s why

   public  static void main(String[] args) {
    	 Father f=new Son();
         f.method1();
     }

Copy the code

The parent’s method1() method was already callable. If we had replaced the parent with a subclass object that had less access to it than the parent, we would not have been able to call it and would not have been able to do so in violation of the Reefer substitution principle.

2. When a subclass overrides a method of its parent class, the subclass method cannot throw more exceptions than the parent class.

public class TestExtends {
     public  static void main(String[] args) {
    	 Father f=new Son();
         try {
			f.method1();
		} catch (Exception e) {
			// TODO Auto-generated catch blocke.printStackTrace(); }}}class Father{
	public void method1(a) throws IOException{}}class Son extends Father{
     public  void method1(a) {}}Copy the code

So in this program, the parent class’s method1 method throws an I/O exception, so when we call it, we try catch it, and if the subclass method doesn’t throw an exception, the subclass object can just replace the parent. But if the parent class’s method1 method does not throw an exception, and the subclass method does when overridden, you can see the program report an error

This is because we don’t need a try catch when we call a superclass method, but we need a try catch when we replace it with a subclass object. In this case, references to the superclass cannot transparently use the subclass object. So we’re not allowed to rewrite methods like this.

What is the reason why two classes cannot inherit

A. Whether or not “is A “matters

B. After the two classes have the “is A “relationship, it is necessary to consider whether the business logic of the subclass object changes after replacing the parent class object. If it changes, the inheritance relationship cannot occur.

Square and rectangle have “is A “relation.

Business scenarios need to be considered. In a particular business scenario, replacing rectangles with squares may lead to changes in business logic.


public class LiskovSubstitutionPrincipleTest {
    public static void main(String[] args) {
    	Rectangle r=new Rectangle();
    	r.setLength(20);
    	r.setWidth(15);
    	System.out.println("Length:"+r.getLength()+","+"Width:"+r.getWidth());
         Utils.change(r);
    	System.out.println("Length:"+r.getLength()+","+"Width:"+r.getWidth());
    	
    	Rectangle square=new Square();
    	square.setLength(12);
    	System.out.println("Length:"+square.getLength()+","+"Width:"+square.getWidth());
    	Utils.change(square);
    	System.out.println("Length:"+square.getLength()+","+"Width:"+square.getWidth()); }}class Rectangle{
	public  double length;
	public  double width;
	public double getLength(a) {
		return length;
	}
	public void setLength(double length) {
		this.length = length;
	}
	public double getWidth(a) {
		return width;
	}
	public void setWidth(double width) {
		this.width = width; }}class Square extends Rectangle{
	public double getLength(a) {
		return length;
	}
	public void setLength(double length) {
		this.length = length;
		this.width=length;
	}
	public double getWidth(a) {
		return width;
	}
	public void setWidth(double width) {
		this.width = width;
		this.length=width; }}class Utils{
	public static void  change(Rectangle r) {
		while(r.getWidth()<=r.getLength()) {
			r.setWidth(r.getWidth()+1);
			System.out.println("Length:"+r.getLength()+","+"Width:"+r.getWidth()); }}}Copy the code

Logical analysis

The business scenario we need to implement here is to increase the width of the rectangle until the width is 1 more than the length, but the square length equals the width property prevents us from implementing this business scenario, that is, the subclass object replaces the parent class object, changing the original business logic. So a square cannot subclass a rectangle in this scenario.