In-depth understanding of polymorphism in java

Polymorphism

Upward transformation

Animal animal = new Bird();

Like this form,The reference of the parent class points to the actual, This is calledUpward transformation

The reference of the parent class can only access its own things, and cannot access the unique properties or methods of the subclass

One sentence summary: the parent class refers to the subclass object


The timing of the upward transformation:
There are three types:

  1. Direct assignment
 Animal animal = new Bird();
  1. Method parameter
public static void func(Animal animal) {
    
    
	
}
public static void main(String[] args) {
    
    
	Dog dog = new Dog();
	func(dog);
}
  1. Method return value
public static Animal func() {
    
    
	Dog dog = new Dog();
	return dog;
}

Downcast

Downward transition will be unsafe, it is best not to use or use less

Animal animal = new Dog();
Dog dog = (Dog)animal;	//需要强制类型转换
dog.wangwang();	//此时可以调用Dog特有的方法
Animal animal = new Dog();
//这里需要判断一下animal是不是Bird的一个实例,是的话才能向下转型
if(animal instanceof Bird) {
    
    
	Bird bird = (Bird)animal;
	bird.fly();	//此时可以访问Bird的特有方法
}

A instanceof B
Is A an instance of B? Does
A refer to the object of B before?

Runtime binding

class Animal {
    
    
    public String name;
    public int age;
    public void eat() {
    
    
        System.out.println("Animal::eat()");
    }
}
class Dog extends Animal1{
    
    

}
public class Test {
    
    
	public static void main(String[] args) {
    
    
		Animal animal = new Dog();
		animal.eat();
	}
}

Run will print at this timeAnimal::eat()

And let’s rewrite the eat method for Dog

class Animal {
    
    
    public String name;
    public int age;
    public void eat() {
    
    
        System.out.println("Animal::eat()");
    }
}
class Dog extends Animal1{
    
    
	public void eat() {
    
    
		System.out.println("Dog::eat()");
	}
}
public class Test {
    
    
	public static void main(String[] args) {
    
    
		Animal animal = new Dog();
		animal.eat();
	}
}

It will printDog::eat() Up

This is because it happened during compile timeRuntime binding, Also calledDynamic binding


Conditions when dynamic binding occurs

  1. Parent class references refer to subclass objects
  2. Call the overriding method of the same name of the parent class and the subclass through the reference of the parent class

Dynamic binding will occur at this time, which is also the premise of polymorphism

Rewrite

Speaking of rewriting here, then I have to review reloading again.

Overload: [in the same class]

  1. Same method name
  2. The parameter list is different
  3. Return value is not required

Override (override): [In inheritance relationship]
Also called overwrite, overwrite

  1. Same method name
  2. The parameter list is the same
  3. The return value is the same

note:

  1. The access rights of the child class cannot be lower than the access rights of the parent class
  2. The method to be rewritten must not be a static method
  3. The method to be rewritten must not be finalized

Understand polymorphism

Let me give you an example

class Shape {
    
    
    public void draw() {
    
    

    }
}

class Rect extends Shape {
    
    
    @Override
    public void draw() {
    
    
        System.out.println("♦");
    }
}

class Cricle extends Shape {
    
    
    @Override
    public void draw() {
    
    
        System.out.println("⭕");
    }
}

class Flower extends Shape {
    
    
    @Override
    public void draw() {
    
    
        System.out.println("❀");
    }
}

//===============================================================
public class TestDemo {
    
    

    public static void drawMap(Shape shape) {
    
    
        shape.draw();;
    }

    public static void main(String[] args) {
    
    
        Rect rect = new Rect();
        drawMap(rect);

        Cricle cricle = new Cricle();
        drawMap(cricle);

        Flower flower = new Flower();
        drawMap(flower);
    }

}

In this code, the code above the dividing line is Class implementor Written, the code below the dividing line is Caller of the class Written.

When the caller of the class is writing the drawMap method, the parameter type is Shape (the parent class). At this time, it is not known inside the method, and it does not care which type (which subclass) the current shape reference points to. Instance. At this point The shape reference to call the draw method may have many different manifestations(Related to the instance corresponding to shape), this behavior is called Polymorphism

The benefits of polymorphism

  1. The use cost of the class caller is further reduced
  • Encapsulation is so that the caller of the class does not need to know the implementation details of the class
  • Polymorphism allows the caller of a class to not even know what the type of the class is, but only needs to know that the object has a certain method.
  1. It can reduce the "cyclocomplexity" of the code and avoid the use of a large number of if-else
    based on the code just now. If it is not based on polymorphism, the code will be very long and complicated
	public static void drawShapes() {
    
    
        Rect rect = new Rect();
        Cycle cycle = new Cycle();
        Flower flower = new Flower();
        String[] shapes = {
    
    "cycle", "rect", "cycle", "rect", "flower"};
        for (String shape : shapes) {
    
    
            if (shape.equals("cycle")) {
    
    
                cycle.draw();
            } else if (shape.equals("rect")) {
    
    
                rect.draw();
            } else if (shape.equals("flower")) {
    
    
                flower.draw();
            }
        }
    }

If you use polymorphism to achieve, you don’t have to write so many if-else branch statements, the code is simpler

	public static void drawShapes() {
    
    
        // 我们创建了一个 Shape 对象的数组.
        Shape[] shapes = {
    
    new Cycle(), new Rect(), new Cycle(),
                new Rect(), new Flower()};
        for (Shape shape : shapes) {
    
    
            shape.draw();
        }
    }
  1. Stronger scalability.
    If you want to add a new shape, the cost of code changes using polymorphism is also relatively low.
class Triangle extends Shape {
    
    
	@Override
	public void draw() {
    
    
		System.out.println("△");
	}
}

core

The core of polymorphism isSo that the caller does not have to pay attention to the specific type of the object

Guess you like

Origin blog.csdn.net/starry1441/article/details/113896343