java polymorphism understanding

Posted by fr34k2oo4 on Sun, 23 Jan 2022 17:50:07 +0100

Understanding of polymorphism:
The so-called polymorphism refers to the specific type pointed to by the reference variable defined in the program and the method call issued through the reference variable. It is not determined during programming, but only during the running of the program, that is, a reference variable will point to the instance object of which class, and the method call issued by the reference variable is the method implemented in which class, It can only be determined during the running of the program. Because the specific class is determined only when the program is running, the reference variable can be bound to various class implementations without modifying the source program code, resulting in the change of the specific method called by the reference, that is, the specific code bound when the program is running can be changed without modifying the program code, so that the program can select multiple running states, This is polymorphism.

clarify
When learning polymorphism, I checked a lot of information on the Internet and found that there are some different versions of polymorphism. Some versions call inheritance and overloading compile time polymorphism; Inheritance and rewriting are called runtime polymorphism. But I don't agree with this method. I think overloading is not polymorphic, inheritance and rewriting are polymorphic.

Polymorphism = = late binding.

Do not interpret function overloading as polymorphic.

Because polymorphism is a runtime behavior, not a compile time behavior.

Polymorphism: a reference to a parent type can point to an object of a child type.

For example, Parent p = new Child();

When calling a method in a polymorphic way, first check whether the method exists in the parent class. If not, the compilation error will occur;

If so, call the method with the same name of the subclass.

In other words, some methods in the parent class must exist in the child class, but some methods in the child class may not exist in the parent class. The child class can have its own unique methods.

Polymorphic sample code

public class PolyTest
{
    public static void main(String[] args)
    {
        
        //Up type conversion
        Cat cat = new Cat();
        Animal animal = cat;
        animal.sing();

                
        //Down type conversion
        Animal a = new Cat();
        Cat c = (Cat)a;
        c.sing();
        c.eat();


        //Compilation error
        //Call a method with a parent class reference that does not exist
        //Animal a1 = new Cat();
        //a1.eat();
        
        //Compilation error
        //Type down conversion can only turn to the object type pointed to        
        //Animal a2 = new Cat();
        //Cat c2 = (Dog)a2;
        


    }
}
class Animal
{
    public void sing()
    {
        System.out.println("Animal is singing!");
    }
}
class Dog extends Animal
{
    public void sing()
    {
        System.out.println("Dog is singing!");
    }
}
class Cat extends Animal
{
    public void sing()
    {
        System.out.println("Cat is singing!");
    }
    public void eat()
    {
        System.out.println("Cat is eating!");
    }
}

Animal a1 = new Cat(); Indicates that a parent class reference can point to a child class object
a1.sing() can run
a1.eat() reports an error because the eat() method is not detected in Animal. The eat() method is unique to Cat subclass.

If you want to use methods specific to subclasses, you need to type down

Animal a1 = new Cat();

Cat c = (Cat) a1;

c.sing(); c.eat(); Can run.

However, downward type conversion can only be converted to the type of subclass object, such as
Animal a2 = new Cat();
Cat c2 = (Dog)a2;
If it is wrong, the compiler will report an error.

Then we are looking at a more complex example:

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

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

}

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

public class C extends B{

}

public class D extends B{

}

public class Test {
    public static void main(String[] args) {
        A a1 = new A();
        A a2 = new B();
        B b = new B();
        C c = new C();
        D d = new D();
        
        System.out.println("1--" + a1.show(b));
        System.out.println("2--" + a1.show(c));
        System.out.println("3--" + a1.show(d));
        System.out.println("4--" + a2.show(b));
        System.out.println("5--" + a2.show(c));
        System.out.println("6--" + a2.show(d));
        System.out.println("7--" + b.show(b));
        System.out.println("8--" + b.show(c));
        System.out.println("9--" + b.show(d));      
    }
}

Output results:

1--A and A
2--A and A
3--A and D
4--B and A
5--B and A
6--A and D
7--B and B
8--B and B
9--A and D

You can see that 1, 2 and 3 may not be a problem, but why is the fourth output B and A instead of B and B? Let's look at the reasons from the behavior of polymorphism at compile and run time.

In the compilation stage, for polymorphic method calls (the parent class reference points to the subclass object), the compiler will first check whether the method is defined by the parent class, and the priority of the judgment method is this show(O),super.show(O),this.show((super)O),super.show((super)O). As long as any one of them exists, even if it is defined in the parent class, the compilation can proceed normally. After the compilation is completed, it enters the run-time stage. The run-time will find the method in the parent class according to the method found in the compilation stage. If the method object is overridden in the child class, it will use the method in the child class object. If it is not overridden, it will use the method in the parent class. Look up in turn and you can always find it.

When a superclass object references a subclass object with a reference variable, the type of the referenced object rather than the type of the reference variable determines whose member method to call. However, the called method must be defined in the superclass, that is, the method overridden by the subclass, but it still needs to confirm the method according to the priority of method calls in the inheritance chain. The priority is this show(O),super.show(O),this.show((super)O),super.show((super)O).

Topics: Java Programming Polymorphism