Upcasting y downcasting son una parte importante de Java, que nos permite crear programas complicados utilizando una sintaxis simple y nos brinda grandes ventajas, como el polimorfismo o la agrupación de diferentes objetos. Java permite que un objeto de un tipo de subclase sea tratado como un objeto de cualquier tipo de superclase. Esto se llama upcasting. La transmisión se realiza automáticamente, mientras que la programación debe realizarla manualmente el programador , y voy a dar lo mejor de mí para explicar por qué es así.
Subir y bajar NO es como lanzar primitivas de uno a otro, y creo que eso es lo que causa mucha confusión, cuando el programador comienza a aprender a lanzar objetos.
Polimorfismo: todos los métodos en Java son virtuales por defecto. Eso significa que cualquier método puede anularse cuando se usa en herencia, a menos que ese método se declare como final o estático .
Puede ver el siguiente ejemplo de cómo getType();
funciona según el tipo de objeto (perro, mascota, perro policía).
Supongamos que tienes tres perros
Perro: esta es la superclase.
Pet Dog - Pet Dog extiende Dog.
Perro policía - Perro policía extiende perro mascota.
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 los métodos en Java son virtuales por defecto. Eso significa que cualquier método puede anularse cuando se usa en herencia, a menos que ese método se declare como final o estático (la explicación pertenece al concepto de tablas virtuales)
Tabla virtual / Tabla de despacho: la tabla de despacho de un objeto contendrá las direcciones de los métodos vinculados dinámicamente del objeto. Las llamadas a métodos se realizan recuperando la dirección del método de la tabla de despacho del objeto. La tabla de despacho es la misma para todos los objetos que pertenecen a la misma clase y, por lo tanto, generalmente se comparte entre ellos.
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();
Huellas dactilares Normal Dog
obj2.getType();
Huellas dactilares Pet Dog
obj3.getType();
Huellas dactilares Police Dog
El programador debe realizar el downcasting manualmente
Cuando intenta invocar el secretID();
método en el obj3
cual se hace PoliceDog object
referencia a Dog
cuál es una superclase en la jerarquía, arroja un error ya obj3
que no tiene acceso al secretId()
método. Para invocar ese método, necesita Downcast que obj3 manualmente para PoliceDog
( (PoliceDog)obj3).secretID();
que imprime ID
De forma similar para invocar el dogName();
método en PetDog
la clase que necesita abatido obj2
a PetDog
desde obj2 está referenciada a Dog
y no tienen acceso a dogName();
método
( (PetDog)obj2).dogName();
¿Por qué es así, que la transmisión es automática, pero la descarga debe ser manual? Bueno, ya ves, la transmisión nunca puede fallar. Pero si usted tiene un grupo de perros diferentes y desea abatido a todos ellos a una de sus tipos, entonces existe la posibilidad de que algunos de estos perros son en realidad de diferentes tipos, es decir, PetDog
, PoliceDog
, y el proceso falla, lanzando ClassCastException
.
Esta es la razón por la que necesita bajar sus objetos manualmente si ha hecho referencia a sus objetos al tipo de superclase.
Nota: Aquí al hacer referencia significa que no está cambiando la dirección de memoria de sus objetos cuando los rechaza, sigue siendo la misma, solo los está agrupando a un tipo particular en este caso Dog
Dog
es unAnimal
. La mayoría de las veces la transmisión es innecesaria a menos que desee utilizar un cierto método sobrecargado.callme
existe en ambosAnimal
yDog
.callme2
solo existe enDog
, en el que echasa
paraDog
que funcione.