Comprensión profunda del polimorfismo en java

Polimorfismo

Transformación ascendente

Animal animal = new Bird();

Como esta forma,La referencia de la clase padre apunta a lo real, Se llamaTransformación ascendente

La referencia de la clase principal solo puede acceder a sus propias cosas y no puede acceder a las propiedades o métodos únicos de la subclase.

Resumen de una oración: la clase principal se refiere al objeto de la subclase


El momento de la transformación ascendente:
hay tres tipos:

  1. Asignación directa
 Animal animal = new Bird();
  1. Parámetro de método
public static void func(Animal animal) {
    
    
	
}
public static void main(String[] args) {
    
    
	Dog dog = new Dog();
	func(dog);
}
  1. Valor de retorno del método
public static Animal func() {
    
    
	Dog dog = new Dog();
	return dog;
}

Alicaído

La transición hacia abajo no será segura, es mejor no usar o usar menos

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的特有方法
}

Una instancia de B
¿Es A una instancia de B? ¿
A se refiere al objeto de B antes?

Enlace en tiempo de ejecución

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();
	}
}

Ejecutar imprimirá en este momentoAnimal :: comer ()

Y reescribamos el método de comer para 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();
	}
}

Se imprimiráPerro :: comer () Arriba

Esto se debe a que sucedió durante el tiempo de compilación.Enlace en tiempo de ejecución, También llamadoEnlace dinámico


Condiciones en las que se produce el enlace dinámico

  1. Las referencias de la clase principal se refieren a objetos de subclase
  2. Llame al método primordial del mismo nombre de la clase principal y la subclase a través de la referencia de la clase principal

La unión dinámica ocurrirá en este momento, que también es la premisa del polimorfismo.

Volver a escribir

Hablando de reescribir aquí, entonces tengo que revisar la recarga nuevamente.

Sobrecarga: [en la misma clase]

  1. Mismo nombre de método
  2. La lista de parámetros es diferente
  3. No se requiere valor de retorno

Anular (anular): [En relación de herencia]
También llamado sobrescribir, sobrescribir

  1. Mismo nombre de método
  2. La lista de parámetros es la misma
  3. El valor de retorno es el mismo

Nota:

  1. Los derechos de acceso de la clase secundaria no pueden ser inferiores a los derechos de acceso de la clase principal
  2. El método a reescribir no debe ser un método estático.
  3. El método a reescribir no debe estar finalizado.

Entender el polimorfismo

Dejame darte un ejemplo

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);
    }

}

En este código, el código sobre la línea divisoria es Implementador de clases Escrito, el código debajo de la línea divisoria es Llamador de la clase Escrito.

Cuando la persona que llama a la clase está escribiendo el método drawMap, el tipo de parámetro es Shape (la clase principal). En este momento, no se conoce dentro del método y no le importa qué tipo (qué subclase) la referencia de forma actual apunta a. Instancia. En este punto La referencia de forma para llamar al método de dibujo puede tener muchas manifestaciones diferentes.(Relacionado con la instancia correspondiente a la forma), este comportamiento se llama Polimorfismo

Los beneficios del polimorfismo

  1. El costo de uso de la persona que llama a la clase se reduce aún más.
  • La encapsulación es para que el llamador de la clase no necesite conocer los detalles de implementación de la clase.
  • El polimorfismo permite que la persona que llama a una clase ni siquiera sepa cuál es el tipo de clase, pero solo necesita saber que el objeto tiene un método determinado.
  1. Puede reducir la "ciclocomplejidad" del código y evitar el uso de una gran cantidad de if-else
    basado en el código en este momento. Si no se basa en polimorfismo, el código será muy largo y complicado.
	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();
            }
        }
    }

Si usa polimorfismo para lograrlo, no tiene que escribir tantas declaraciones de rama if-else, el código es más simple

	public static void drawShapes() {
    
    
        // 我们创建了一个 Shape 对象的数组.
        Shape[] shapes = {
    
    new Cycle(), new Rect(), new Cycle(),
                new Rect(), new Flower()};
        for (Shape shape : shapes) {
    
    
            shape.draw();
        }
    }
  1. Mayor escalabilidad.
    Si desea agregar una nueva forma, el costo de los cambios de código usando polimorfismo también es relativamente bajo.
class Triangle extends Shape {
    
    
	@Override
	public void draw() {
    
    
		System.out.println("△");
	}
}

centro

El núcleo del polimorfismo esPara que la persona que llama no tenga que prestar atención al tipo específico de objeto

Supongo que te gusta

Origin blog.csdn.net/starry1441/article/details/113896343
Recomendado
Clasificación