Java básico | polimorfismo

Significado polimórfico

O polimorfismo é um tipo, formas múltiplas.
Java é dividido principalmente em duas categorias: o
polimorfismo do método se
reflete na sobrecarga e na substituição do método.
O polimorfismo de objeto é
refletido na transformação entre objetos pais e filhos. (Existe uma relação de herança entre pai e filho)

Classe dos pais

Transformação para cima

A referência do supertipo aponta para o objeto do subtipo.

子类型转换成父类型
向上转型
自动类型转换
Persoon a=new Student();
a.fun()

A referência a do supertipo aponta para um objeto de subtipo na memória da pilha.
! ! !
Mas no compilador java, apenas o tipo pai é reconhecido para a.
O compilador detecta que o tipo de dados de a é o tipo Person.
! ! ! Mas na fase de apontar, como os objetos que realmente existem na camada inferior são subclasses, eles ainda são objetos das subclasses em execução.
Up-casting, o compilador depende da classe pai, e o executor depende da subclasse

java程序永远分为编译阶段和运行阶段;
先分析编译阶段,再分析运行阶段,编译无法通过,就无法运行
编译阶段的编译器检查a这个引用的数据类型为Person,
当person.class字节码当中存在的fun()方法,a.fun()编译才能通过。
只有静态绑定成功之后才有后续的运行。

但是在程序的运行阶段,JVM堆内存中真实的对象是Student对象,
那么a.fun()一定会调用Student的fun方法,
此时,发生了程序的动态绑定,运行阶段绑定
class Person
{
    
    
	public void fun1()
	{
    
    
		System.out.println("****fun1,来自父类");
	}
	public void fun2(int a)
	{
    
    
		System.out.println("****fun2,来自父类"+a);
	}

	public void fun3()
	{
    
    
		System.out.println("****fun3,来自父类");
	}
}

class Student extends Person
{
    
    
	public void fun1()
	{
    
    
		System.out.println("****fun1,来自子类");
	}
	public void fun2(int c,int b)
	{
    
    
		System.out.println("****fun2,来自子类"+(c+b));
	}
	/*public void fun2(int a)
	{
		System.out.println("****fun2,来自子类"+a);
	}*/
	public void fun4()
	{
    
    
		System.out.println("****fun4,来自子类");
	}
}
public class Test
{
    
    
	public static void main(String[] args)
	{
    
    
		//向上转型
		//编译器取决于父类,执行器取决于子类
		Person p=new Student();
		p.fun1();//方法覆写时,执行子类的,因为底层真实存在的是子类对象

		p.fun2(2);//方法重载时,将自动执行父类的
		((Student)p).fun2(2,3);//向下转型//方法重载时,若要执行子类方法,需要强制转化为子类方法

		p.fun3();//向上转型,父类所有方法都可以直接调用
		((Student)p).fun4();//向上转型,只有子类存在的方法,需要强制转化
	}
}

Insira a descrição da imagem aqui

Quando os métodos são compartilhados e iguais, ele aponta para a subclasse; (por causa da transformação para cima, o objeto subjacente é o objeto da subclasse)
.Quando o método não existe na subclasse, ele aponta para a classe pai;

原因是:父类型引用执行子类型,导致程序在编译阶段绑定和运行阶段绑定
出现了两种不同的状态

Abatido

Você pode adicionar diretamente ((Aluno) p) .fun2 (2,3);
também pode ser alterado para Aluno S = (Aluno) p; S.fun2 (2,3)

Quando o método chamado é exclusivo para o subtipo e não existe no tipo pai, deve ser feito o downcast. A
classe pai passa para a classe filha e há uma relação de herança entre as duas. A
classe pai não existe, e a classe filha existe (precisa ser aplicada para executar a subcategoria)

Subcategoria

Se ambas as classes herdarem de um
erro de classe pai 1 , como

Student 和Teacher 都继承了Person

Então

		Person p=new Student();
		Teacher T=(Teacher)p;

A transformação mútua das duas subclasses pode ser passada no estágio do compilador, mas não pode ser executada.
Motivo: como o compilador detecta que o tipo de dados de p é Pessoa,
há herança entre Pessoa e Professor, e Pessoa é um supertipo e Professor é um subtipo, que é um downcast, e a sintaxe é qualificada.

Mas o programa será anormal quando estiver em execução. Como a existência real na memória heap da JVM é o Aluno e não há herança entre o Aluno e o Professor e eles não podem ser transformados um no outro, ocorre a exceção ClassCastException , que sempre ocorre durante a transformação para baixo.
Transformação para baixo, a compilação é passada, mas a operação não é necessariamente errada e existem riscos de segurança.
Transformação para cima, desde que a compilação tenha sido concluída, não haverá problemas com a operação. O
Insira a descrição da imagem aqui
acima é a exceção ClassCastException.

Como evitar exceções durante o down-casting

Os pontos principais acima: apenas evite, não resolva.
Porque duas subclasses que não têm relacionamento de herança não podem se transformar.

Operador: instanceof

Formato da sintaxe:
(citação da instância do nome do tipo de dados)
** Resultado da execução da operação: ** Tipo booleano, verdadeiro ou falso
Sobre o resultado da operação: verdadeiro e falso

	(p instanceof Person)
true表示:
	p这引用指向的对象是Person类型
fals表示:
	p这个引用,指向的对象不是一个Person类型

exemplo

//如何避免
		if(p instanceof Teacher)//如果p是一个teacher类型对象
		{
    
    
			Teacher T=(Teacher) p;
			p.fun1();
		}
		else if(p instanceof Student)//如果是一个Student类型对象
		{
    
    
			Student S=(Student)p;
			S.fun4();
		}
		//为什么这么做呢???判断其是引用P是哪个类型对象后,
		//再将其强制转换,赋予一个新的引用。这个现在可能看不出来,
		//但是以后子类多了,进行instanceof判断,避免Exception异常,
		//这是一个编程的好习惯,并不是必须写。

Por que você faz isso? ? ? Depois de julgar a que tipo de objeto ele se refere a P,
ele é forçado a converter e uma nova referência é atribuída. Isso pode não estar visível agora,
mas haverá mais subclasses no futuro, para executar instâncias de julgamentos para evitar a Exceção,
este é um bom hábito de programação e não é necessário escrever.
Após a instância de julgamento, há uma nova referência, esta referência, ao chamar o método da subclasse, não há necessidade de lançar um por um.


Applets

class Master
{
    
    
	public void feed(Cat c)
	{
    
    
		c.eat();
	}
}

class Cat
{
    
    
	public void eat()
	{
    
    
		System.out.println("小猫在吃鱼");
	}
}

public class Test
{
    
    
	public static void main(String[] args)
	{
    
    
		Master m=new Master();
		Cat c=new Cat();
		m.feed(c);
	}
}

Insira a descrição da imagem aqui
No entanto, se eu precisar adicionar um cachorrinho para comer, o coelhinho come vegetais e o tigre come carne

基础的各项小动物类都要写
而且在Master里都要加上
public void feed(Dog d)
	{
    
    
		d.eat();
	}
	public void feed(Tuz t)
	{
    
    
		t.eat();
	}
	public void feed(Hu h)
	{
    
    
		h.eat();
	}

Isso é muito incômodo
. Na verdade, são todas manifestações de um método;
como fazer esse método para que, quando a função principal for chamada, não haja necessidade de o Mestre fazer grandes mudanças.
Isso é fazer com que o animal herde o capacidade do animal de estimação de comer este pacote de habilidades
e, em seguida, O alimento (x) do Mestre, o tipo de dados de x são animais de estimação, então ,
o alimento (x), x é uma referência, é uma referência do tipo de dados do animal de estimação, então ele pode apontar para animais de estimação, ou pode apontar para subcategorias de animais de estimação, gatos e cachorros

class Master
{
    
    
	public void feed(Pet c)
	{
    
    
		c.eat();
	}
}

class Pet
{
    
    
	public void eat()
	{
    
    
	}
}

class Cat extends Pet//子类猫狗继承了 宠物的吃 行为
{
    
    
	public void eat()
	{
    
    
		System.out.println("小猫在吃鱼");
	}
}

class Dog extends Pet
{
    
    
	public void eat()
	{
    
    
		System.out.println("小狗在吃s");
	}
}

public class Test
{
    
    
	public static void main(String[] args)
	{
    
    
		Master m=new Master();
		Cat c=new Cat();//在堆内存创建了一个猫对象
		m.feed(c);//feed(c0) c0又是一个宠物引用,而宠物和猫阿狗有继承关系,所以将执行子类的函数
		Dog d=new Dog();
		m.feed(d);
	}
}

Para fazer isso, você só precisa adicionar uma pequena classe de animais e pet herdar;
Mestre refere-se ao tipo de dados de Pet (a classe pai deve ter um método que é o mesmo que nós precisamos de uso.)
Gerar o animal no principal método Object, e de acordo com a referência do tipo de dados Pet aprendido anteriormente, ao enfrentar os subobjetos de Pet, a camada inferior é, na verdade, as subclasses de Pet Cat, Dog, etc. O
acima também é uma programação orientada à abstração, com baixo acoplamento e forte expansão., Veja
o papel do polimorfismo na classe Pet , reduza o acoplamento do programa e melhore a extensibilidade.
Defensor: o uso de programação orientada a abstratas. A classe Pet comer é abstrata e vazia e, de fato, quando suas subclasses são chamadas, os dois herdam O relacionamento faz o ponto de referência do tipo de dados Pet para o objeto da subclasse e executa o método da subclasse.

Acho que você gosta

Origin blog.csdn.net/weixin_46096297/article/details/114679999
Recomendado
Clasificación