Compreensão aprofundada do polimorfismo em java

Polimorfismo

Transformação para cima

Animal animal = new Bird();

Como este formulário,A referência da classe pai aponta para o real, Isso é chamadoTransformação para cima

A referência da classe pai só pode acessar suas próprias coisas e não pode acessar as propriedades ou métodos exclusivos da subclasse

Resumo de uma frase: a classe pai refere-se ao objeto da subclasse


O momento da transformação para cima:
Existem três tipos:

  1. Atribuição direta
 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 do método
public static Animal func() {
    
    
	Dog dog = new Dog();
	return dog;
}

Abatido

A transição para baixo não será segura, é melhor não usar ou 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的特有方法
}

A instância de B A
é uma instância de B?
A se refere ao objeto de B antes?

Ligação de tempo de execução

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

Executar irá imprimir neste momentoAnimal :: comer ()

E vamos reescrever o método de comer para Cachorro

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

Vai imprimirCachorro :: comer () Acima

Isso ocorre porque aconteceu durante o tempo de compilaçãoLigação de tempo de execução, Também chamadoLigação dinâmica


Condições quando a ligação dinâmica ocorre

  1. Referências de classe pai referem-se a objetos de subclasse
  2. Chame o método de substituição com o mesmo nome da classe pai e da subclasse por meio da referência da classe pai

A ligação dinâmica ocorrerá neste momento, que também é a premissa do polimorfismo

Reescrever

Falando em reescrever aqui, tenho que revisar o recarregamento novamente.

Sobrecarga: [na mesma classe]

  1. Mesmo nome de método
  2. A lista de parâmetros é diferente
  3. O valor de retorno não é obrigatório

Substituir (substituir): [Na relação de herança]
Também chamado de substituir, substituir

  1. Mesmo nome de método
  2. A lista de parâmetros é a mesma
  3. O valor de retorno é o mesmo

Nota:

  1. Os direitos de acesso da classe infantil não podem ser inferiores aos direitos de acesso da classe pai
  2. O método a ser reescrito não deve ser um método estático
  3. O método a ser reescrito não deve ser finalizado

Entenda o polimorfismo

Deixe-me lhe dar um exemplo

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

}

Neste código, o código acima da linha divisória é Implementador de classe Escrito, o código abaixo da linha divisória é Chamador da classe Escrito.

Quando o chamador da classe está escrevendo o método drawMap, o tipo de parâmetro é Shape (a classe pai). No momento, ele não é conhecido dentro do método e não se importa com qual tipo (qual subclasse) a referência de forma atual aponta para. Instância. Neste ponto A referência de forma para chamar o método de desenho pode ter muitas manifestações diferentes(Relacionado à instância correspondente à forma), este comportamento é chamado Polimorfismo

Os benefícios do polimorfismo

  1. O custo de uso do chamador da classe é ainda mais reduzido
  • O encapsulamento é feito para que o chamador da classe não precise saber os detalhes de implementação da classe
  • O polimorfismo permite que o chamador de uma classe nem saiba qual é o tipo da classe, mas só precisa saber que o objeto possui um determinado método.
  1. Pode reduzir a "ciclocomplexidade" do código e evitar o uso de um grande número de if-else com
    base no código agora. Se não for baseado em polimorfismo, o código será muito longo e 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();
            }
        }
    }

Se você usar polimorfismo para conseguir, você não precisa escrever tantas instruções de desvio if-else, o código é mais simples

	public static void drawShapes() {
    
    
        // 我们创建了一个 Shape 对象的数组.
        Shape[] shapes = {
    
    new Cycle(), new Rect(), new Cycle(),
                new Rect(), new Flower()};
        for (Shape shape : shapes) {
    
    
            shape.draw();
        }
    }
  1. Escalabilidade mais forte.
    Se você deseja adicionar uma nova forma, o custo das alterações de código usando o polimorfismo também é relativamente baixo.
class Triangle extends Shape {
    
    
	@Override
	public void draw() {
    
    
		System.out.println("△");
	}
}

essencial

O núcleo do polimorfismo éPara que o chamador não tenha que prestar atenção ao tipo específico do objeto

Acho que você gosta

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