Upcasting e downcasting são parte importante do Java, que nos permite criar programas complicados usando sintaxe simples e nos oferece grandes vantagens, como polimorfismo ou agrupamento de objetos diferentes. Java permite que um objeto de um tipo de subclasse seja tratado como um objeto de qualquer tipo de superclasse. Isso é chamado upcasting. O upcasting é feito automaticamente, enquanto o downcasting deve ser feito manualmente pelo programador , e eu darei o meu melhor para explicar por que é isso.
Upcasting e downcasting NÃO são como converter primitivas de uma para outra, e acredito que é isso que causa muita confusão, quando o programador começa a aprender a moldar objetos.
Polimorfismo: Todos os métodos em java são virtuais por padrão. Isso significa que qualquer método pode ser substituído quando usado em herança, a menos que esse método seja declarado como final ou estático .
Você pode ver o exemplo abaixo como getType();
funciona de acordo com o tipo de objeto (Cão, Animal de estimação, Cão policial).
Suponha que você tem três cães
Dog - Esta é a super classe.
Pet Dog - Pet Dog estende Dog.
Cão de Polícia - Cão de Polícia estende Dog Pet.
public class Dog{
public String getType () {
System.out.println("NormalDog");
return "NormalDog";
}
}
/**
* Pet Dog has an extra method dogName()
*/
public class PetDog extends Dog{
public String getType () {
System.out.println("PetDog");
return "PetDog";
}
public String dogName () {
System.out.println("I don't have Name !!");
return "NO Name";
}
}
/**
* Police Dog has an extra method secretId()
*/
public class PoliceDog extends PetDog{
public String secretId() {
System.out.println("ID");
return "ID";
}
public String getType () {
System.out.println("I am a Police Dog");
return "Police Dog";
}
}
Polimorfismo: Todos os métodos em java são virtuais por padrão. Isso significa que qualquer método pode ser substituído quando usado em herança, a menos que esse método seja declarado como final ou estático (a explicação pertence ao conceito de tabelas virtuais)
Tabela Virtual / Tabela de Despacho: A tabela de despacho de um objeto conterá os endereços dos métodos vinculados dinamicamente ao objeto. As chamadas de método são realizadas buscando o endereço do método na tabela de despacho do objeto. A tabela de expedição é a mesma para todos os objetos pertencentes à mesma classe e, portanto, geralmente é compartilhada entre eles.
public static void main (String[] args) {
/**
* Creating the different objects with super class Reference
*/
Dog obj1 = new Dog();
` /**
* Object of Pet Dog is created with Dog Reference since
* Upcasting is done automatically for us we don't have to worry about it
*
*/
Dog obj2 = new PetDog();
` /**
* Object of Police Dog is created with Dog Reference since
* Upcasting is done automatically for us we don't have to worry
* about it here even though we are extending PoliceDog with PetDog
* since PetDog is extending Dog Java automatically upcast for us
*/
Dog obj3 = new PoliceDog();
}
obj1.getType();
Impressões Normal Dog
obj2.getType();
Impressões Pet Dog
obj3.getType();
Impressões Police Dog
O downcasting precisa ser feito manualmente pelo programador
Quando você tenta invocar o secretID();
método no obj3
qual é PoliceDog object
referenciado, mas Dog
que é uma superclasse na hierarquia, gera erro, pois obj3
não tem acesso ao secretId()
método. Para invocar esse método, você precisa fazer o downcast desse obj3 manualmente para PoliceDog
( (PoliceDog)obj3).secretID();
que imprime ID
No caminho semelhante ao invocar o dogName();
método na PetDog
classe que você precisa para downcast obj2
para PetDog
desde obj2 é referenciado para Dog
e não têm acesso ao dogName();
método
( (PetDog)obj2).dogName();
Por que é assim, que o upcasting é automático, mas o downcasting deve ser manual? Bem, veja bem, o upcasting nunca pode falhar. Mas se você tem um grupo de cães diferentes e quer downcast los todos para um de seus tipos, então há uma chance de que alguns destes cães são realmente de diferentes tipos ou seja, PetDog
, PoliceDog
, e processo falhar, atirando ClassCastException
.
Esse é o motivo pelo qual você precisa fazer o downcast de seus objetos manualmente, se você os referenciou ao tipo de superclasse.
Nota: Aqui, por referência, significa que você não está alterando o endereço de memória de seus objetos quando o faz downcast, ele ainda permanece o mesmo; você apenas os agrupa para um tipo específico neste caso Dog
Dog
é umAnimal
. Na maioria das vezes, o upcasting é desnecessário, a menos que você queira usar um determinado método sobrecarregado.callme
existe em ambosAnimal
eDog
.callme2
só existe emDog
que você jogaa
paraDog
torná-lo trabalho.