Problems encountered in overloading and rewriting (overwriting) in java

heavy load

Nearest matching principle

The basic conditions and principles of overloading are not introduced in detail here, but there are a lot of online introductions. Here is a record of an example encountered when watching Zen of design patterns. This example involves the recent matching principle of overloading, which has not been paid much attention to before.

Father class source code:

public class Father {      
     public Collection doSomething(HashMap map){
             System.out.println("The parent class is executed...");    
             return map.values();
     }
}

Subclass source code:

public class Son extends Father {
     //Enlarge input parameter type
     public Collection doSomething(Map map){
             System.out.println("Subclass is executed...");
             return map.values();
     }
}

Note that this is not an override, because the parameters are different. The parameters of the methods in the subclass are the parent of the parameters in the parent method, which is equivalent to expanding the type range of the parameters. This is method overloading between subclasses and superclasses.

Next test:

public class Client {
     public static void invoker(){
             //Where the parent class exists, the child class should exist
             Father f = new Father();
             HashMap map = new HashMap();
             f.doSomething(map);
     }
     public static void main(String[] args) {
             invoker();
     }
}

The output result is

The parent class is executed...

It is supposed to be such a result here, but Father f = new Father(); When the code is changed as follows:

public class Client {
     public static void invoker(){
             //Where the parent class exists, the child class should exist
             Son f =new Son();
             HashMap map = new HashMap();
             f.doSomething(map);
     }
     public static void main(String[] args) {
             invoker();
     }
}

In this case, should I call the methods of the subclass or the parent class?

It is revealed that the method of the parent class is called. The output result is the same as the above. This is because the method is matched according to the overloaded nearest matching principle. In this way, the method in the parent class will be called, and the method of the child class will not be called.

HashMap -- > map is a subclass parent relationship. The parameter HashMap map = new HashMap() passed in will match HashMap first, so the method of the parent class will be found naturally.

Here is an example of the principle of Richter's substitution in Zen of design patterns, which embodies the principle of Richter's substitution

When overriding or implementing the methods of the parent class, the input parameters can be amplified

The input parameter of the parent class method is HashMap type, and the input parameter of the subclass is Map type, that is to say, the scope of the input parameter type of the subclass is expanded. The subclass is passed to the caller instead of the parent class, and the subclass method will never be executed. This is correct. If you want the methods of the subclass to run, you must override the methods of the parent class.

rewrite

There are also many details about rewriting on the Internet. Here is a blog I saw. I encountered the above overload problem when I queried it, which is also very interesting.

For the following examples:

package myTest;


class A {
    public String show(D obj) {
        return ("A and D");
    }

    public String show(A obj) {
        return ("A and A");
    }
}

class B extends A {

    @Override
    public String show(A obj) {
        return ("B and A");
    }

    public String show(B obj) {
        return ("B and B");
    }
}

class C extends B {
}

class D extends B {
}

/**
 * @author luwanglin
 * @email 1769862620@qq.com
 * @Date 2020/9/18 15:34
 * @Version 1.0
 */
public class MultiTest {
    public static void main(String[] args) {
        A ab = new B();
        B b = new B();
        C c = new C();

        System.out.println(ab.show(b));
        System.out.println(ab.show(c));
        System.out.println(b.show(c));
    }
}

The inheritance diagram is as follows:

The operation results are as follows:

B and A
B and A
B and B

The questions raised are:

Why aren't the first two results

B and B 
B and B 

The third result can be explained according to the above nearest matching principle.

Record the better answers you see online:

A ab = new B(); 
here ab The reference type of is A,But the memory it points to is of type B An example of

Think right ab For method calls, the methods you call must be class A Only if there is something in it (because your reference type is A)
here class A have show(A obj) show(D obj)There are two ways

ab.show(b) stay class A No method of type matching was found in, but b After type promotion, you can find show(A obj)Method, similarly ab.show(c)Also show(A obj)method; however ab The memory address points to a file of type B Memory space, if class B Override Yes class A of show(A obj)Method, call B Method, otherwise, call A Own method

Can guess  D d = new D();  ab.show(d)The result is A and D
 If you comment out class A of  show(A obj)method, ab.show(b)  ab.show(c)Will make mistakes.

Here, you just need to remember that the methods that can be called are determined by the reference type, and the specific implementation is determined by the actual memory object type
  • When java executes a method, it will get the corresponding method according to the type of the object. If there is no error during compilation, it will be dynamically matched during real execution. If the real object is a subclass and this method is overwritten in the subclass, it will execute the subclass method.
  • When java types are matched, if they cannot be matched, type up and convert them into parent classes until they can be matched. If they cannot be matched all the time, an error will be reported during compilation.
  • The upward transformation in java polymorphism. In short, the parent class reference generates a subclass object, and this reference can only call the properties and methods already defined in the parent class, but cannot access the properties and methods newly defined by the subclass itself. For example, your A ab=new B();,ab is a parent class reference, and then execute ab.show(b). At this time, AB first finds the method from the parent class, and only show(A obj) method matches it. Moreover, it is found that the subclass rewrites the method. At this time, it is dynamically linked to the show(A obj) method of the subclass.
    If you execute b.show(c), there are show(A obj) method and show (B obj) method in B. the inheritance level is C - > b - > A. according to the overloaded nearest match principle, the show (B obj) method will be called.

Reference articles

Tags: Java

Posted by Jr0x on Mon, 16 May 2022 04:36:10 +0300