¿Cuál es la diferencia entre up-cast y down-cast con respecto a la variable de clase?
Por ejemplo, en la siguiente clase de programa Animal contiene solo un método, pero la clase Dog contiene dos métodos, y luego cómo convertimos la variable Dog en Animal Variable.
Si se realiza el lanzamiento, ¿cómo podemos llamar al perro otro método con la variable Animal?
class Animal
{
public void callme()
{
System.out.println("In callme of Animal");
}
}
class Dog extends Animal
{
public void callme()
{
System.out.println("In callme of Dog");
}
public void callme2()
{
System.out.println("In callme2 of Dog");
}
}
public class UseAnimlas
{
public static void main (String [] args)
{
Dog d = new Dog();
Animal a = (Animal)d;
d.callme();
a.callme();
((Dog) a).callme2();
}
}
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.Respuestas:
Upcasting se convierte a un supertipo, mientras que downcasting se convierte a un subtipo. La conversión hacia arriba siempre está permitida, pero la conversión hacia abajo implica una verificación de tipo y puede arrojar un
ClassCastException
.En su caso, un reparto de un
Dog
a unAnimal
es un upcast, porque unDog
is-aAnimal
. En general, puede transmitir cuando haya una relación is-a entre dos clases.Downcasting sería algo como esto:
Básicamente lo que hace es decirle al compilador que usted sabe lo que el tipo de ejecución del objeto realmente es. El compilador permitirá la conversión, pero seguirá insertando una comprobación de sanidad en tiempo de ejecución para asegurarse de que la conversión tenga sentido. En este caso, la conversión es posible porque en tiempo de ejecución
animal
es realmenteDog
aunque el tipo estático deanimal
esAnimal
.Sin embargo, si hicieras esto:
Conseguirías un
ClassCastException
. La razón es porqueanimal
el tipo de tiempo de ejecución esAnimal
, y cuando le dices al tiempo de ejecución que realice el lanzamiento, ve queanimal
no es realmente aDog
y por lo tanto arroja aClassCastException
.Para llamar al método de una superclase, puede hacerlo
super.method()
o realizando la transmisión ascendente.Para llamar al método de una subclase, debe hacer un downcast. Como se muestra arriba, normalmente corre el riesgo
ClassCastException
de hacer esto; sin embargo, puede usar elinstanceof
operador para verificar el tipo de tiempo de ejecución del objeto antes de realizar el lanzamiento, lo que le permite evitarClassCastException
s:fuente
ClassCastException
o no? ¿Como en el primer caso?Down-casting y up-casting fue el siguiente:
Upcasting : cuando queremos lanzar una Subclase a Super class, usamos Upcasting (o ensanchamiento). Sucede automáticamente, no es necesario hacer nada explícitamente.
Downcasting : cuando queremos lanzar una Superclase a Subclase, usamos Downcasting (o estrechamiento), y Downcasting no es directamente posible en Java, explícitamente tenemos que hacerlo.
fuente
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.
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)
Huellas dactilares
Normal Dog
Huellas dactilares
Pet Dog
Huellas dactilares
Police Dog
El programador debe realizar el downcasting manualmente
Cuando intenta invocar el
secretID();
método en elobj3
cual se hacePoliceDog object
referencia aDog
cuál es una superclase en la jerarquía, arroja un error yaobj3
que no tiene acceso alsecretId()
método. Para invocar ese método, necesita Downcast que obj3 manualmente paraPoliceDog
que imprime
ID
De forma similar para invocar el
dogName();
método enPetDog
la clase que necesita abatidoobj2
aPetDog
desde obj2 está referenciada aDog
y no tienen acceso adogName();
método¿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, lanzandoClassCastException
.Esta es la razón por la que necesita bajar sus objetos manualmente si ha hecho referencia a sus objetos al tipo de superclase.
fuente
Sé que esta pregunta se hizo hace bastante tiempo, pero para los nuevos usuarios de esta pregunta. Lea este artículo donde contiene una descripción completa sobre la transmisión, la descarga y el uso de la instancia del operador
No hay necesidad de transmitir manualmente, sucede solo:
Mammal m = (Mammal)new Cat();
igual aMammal m = new Cat();
Pero el downcasting siempre debe hacerse manualmente:
¿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 tiene un grupo de animales diferentes y desea rechazarlos a un gato, existe la posibilidad de que algunos de estos animales sean perros y el proceso falle lanzando ClassCastException. Aquí es donde debe introducir una característica útil llamada "instancia de" , que prueba si un objeto es una instancia de alguna clase.
Para más información por favor lea este artículo
fuente
Mejor pruebe este método para la transmisión, es fácil de entender:
fuente
Quizás esta tabla ayude. Llamando al
callme()
método de claseParent
o claseChild
. Como principiofuente
1.- Upcasting.
Al realizar una conversión ascendente, define una etiqueta de algún tipo, que apunta a un objeto de un subtipo (Tipo y subtipo pueden llamarse clase y subclase, si se siente más cómodo ...).
Lo que significa que dicha etiqueta, animalCat, tendrá la funcionalidad (los métodos) de tipo Animal solamente, porque la hemos declarado como tipo Animal, no como tipo Cat.
Se nos permite hacerlo de forma "natural / implícita / automática", en tiempo de compilación o en tiempo de ejecución, principalmente porque Cat hereda parte de su funcionalidad de Animal; por ejemplo, move (). (Al menos, el gato es un animal, ¿no?)
2.- Downcasting.
Pero, ¿qué sucedería si necesitamos obtener la funcionalidad de Cat, de nuestra etiqueta Animal tipo?
Como hemos creado la etiqueta animalCat que apunta a un objeto Cat, necesitamos una forma de llamar a los métodos del objeto Cat, desde nuestra etiqueta animalCat de una manera bonita e inteligente.
Tal procedimiento es lo que llamamos Downcasting, y solo podemos hacerlo en tiempo de ejecución.
Tiempo para un código:
fuente
Padre: Coche
Niño: Figo
Coche c1 = nuevo Figo ();
=====
Upcasting: -
Método: el objeto c1 se referirá a Métodos de clase (Figo - El método debe ser anulado) porque la clase "Figo" se especifica con "nuevo".
Variable de instancia: el objeto c1 se referirá a la variable de instancia de la clase de declaración ("Auto").
Cuando la clase de declaración es primaria y se crea un objeto secundario, se produce una conversión implícita que es "Upcasting".
======
Downcasting: -
Figo f1 = (Figo) c1; //
Método: el objeto f1 se referirá al Método de clase (figo) ya que el objeto inicial c1 se crea con la clase "Figo". pero una vez que se realiza la conversión, los métodos que solo están presentes en la clase "Figo" también pueden ser referidos por la variable f1.
Variable de instancia: el objeto f1 no se referirá a la variable de instancia de la clase de declaración del objeto c1 (la clase de declaración para c1 es CAR) pero con la conversión descendente se referirá a las variables de instancia de la clase Figo.
======
Uso: cuando el objeto es de clase secundaria y la clase de declaración es primaria y la clase secundaria quiere acceder a la variable de instancia de su propia clase y no de la clase primaria, entonces se puede hacer con "Downcasting".
fuente
la conversión ascendente significa lanzar el objeto a un supertipo, mientras que la conversión descendente significa emitir a un subtipo.
En java, la transmisión no es necesaria, ya que se realiza automáticamente. Y generalmente se conoce como casting implícito. Puede especificarlo para dejarlo claro a los demás.
Así, escribiendo
o
conduce exactamente al mismo punto y en ambos casos se ejecutará
callme()
desdeDog
.Downcasting es necesario porque lo definiste
a
como objeto de Animal. Actualmente sabes que es unDog
, pero Java no tiene garantías de que lo sea. En realidad, en tiempo de ejecución podría ser diferente y Java arrojará unClassCastException
, si eso sucediera. Por supuesto, no es el caso de su ejemplo de muestra. Si no echaríaa
aAnimal
, java ni siquiera podía compilar la aplicación, ya queAnimal
no tiene métodocallme2()
.En su ejemplo no puede comunicarse con el código de
callme()
deAnimal
deUseAnimlas
(porqueDog
sobreescribirla) a menos que el método sería de la siguiente manera:fuente
Podemos crear objetos para Downcasting. En este tipo también. : llamar a los métodos de la clase base
fuente