qué cast java casting class-variables downcasting upcasting

qué - downcasting java



¿Cuál es la diferencia entre up-casting y down-casting con respecto a la variable de clase (9)

Down-casting y up-casting fue el siguiente:

Upcasting : cuando queremos convertir una Subclase en Súper clase, utilizamos Upcasting (o ampliación). Sucede automáticamente, no hay necesidad de hacer nada explícitamente.

Downcasting : cuando queremos lanzar una clase Super a Sub class, utilizamos Downcasting (o narrowing), y Downcasting no es directamente posible en Java, explícitamente tenemos que hacerlo.

Dog d = new Dog(); Animal a = (Animal) d; //Explicitly you have done upcasting. Actually no need, we can directly type cast like Animal a = d; compiler now treat Dog as Animal but still it is Dog even after upcasting d.callme(); a.callme(); // It calls Dog''s method even though we use Animal reference. ((Dog) a).callme2(); // Downcasting: Compiler does know Animal it is, In order to use Dog methods, we have to do typecast explicitly. // Internally if it is not a Dog object it throws ClassCastException

¿Cuál es la diferencia entre up-casting y down-casting 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 aplicamos la variable Dog a la Variable Animal.

Si se realiza el lanzamiento, ¿cómo podemos llamar al Perro otro método con la variable de 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(); } }


Es mejor probar este método para el upcasting, es fácil de entender:

/* upcasting problem */ 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) { Animal animal = new Animal (); Dog dog = new Dog(); Animal ref; ref = animal; ref.callme(); ref = dog; ref.callme(); } }


Padre: Coche
Niño: Figo
Coche c1 = nuevo Figo ();

=====
Upcasting: -
Método: El objeto c1 se referirá a los 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 ("Car").

Cuando la clase de declaración es principal y el objeto se crea de secundario, ocurre 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) como el objeto inicial c1 se crea con la clase "Figo". pero una vez que se realiza el lanzamiento descendente, los métodos que solo están presentes en la clase "Figo" también pueden referirse mediante 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 el down casting se referirá a las variables de instancia de la clase Figo.

======
Uso: Cuando Object es de clase infantil y la clase de declaración es primaria y secundaria, la clase quiere acceder a la variable de instancia de su propia clase y no de la clase principal, entonces se puede hacer con "Downcasting".


Podemos crear un objeto para Downcasting. En este tipo también : llamando a los métodos de clase base

Animal a=new Dog(); a.callme(); ((Dog)a).callme2();


Quizás esta mesa ayude. Llamando al método callme() de la clase Parent o clase Child . Como principio:

UPCASTING -> Ocultar

DOWNCASTING -> Revelador


Sé que esta pregunta hace mucho tiempo, pero para los nuevos usuarios de esta pregunta. Por favor, lea este artículo donde contiene una descripción completa sobre upcasting, downcasting y uso del operador de instanceof

  • No hay necesidad de actualizar manualmente, sucede por sí solo:

    Mammal m = (Mammal)new Cat(); es igual a Mammal m = new Cat();

  • Pero downcasting siempre debe hacerse manualmente:

    Cat c1 = new Cat(); Animal a = c1; //automatic upcasting to Animal Cat c2 = (Cat) a; //manual downcasting back to a Cat

¿Por qué es eso así, que el upcasting es automático, pero downcasting debe ser manual? Bueno, ya ves, upcasting nunca puede fallar. Pero si tienes un grupo de diferentes animales y quieres enviarlos todos a un gato, existe la posibilidad de que algunos de estos animales sean en realidad perros y el proceso falle lanzando ClassCastException. Aquí es donde debe introducirse una característica útil llamada "instanceof" , que prueba si un objeto es instancia de alguna Clase.

Cat c1 = new Cat(); Animal a = c1; //upcasting to Animal if(a instanceof Cat){ // testing if the Animal is a Cat System.out.println("It''s a Cat! Now i can safely downcast it to a Cat, without a fear of failure."); Cat c2 = (Cat)a; }

Para obtener más información, lea este artículo


Upcasting está lanzando a un supertipo, mientras que downcasting está lanzando a un subtipo. Upcasting siempre está permitido, pero downcasting implica una verificación de tipo y puede lanzar una ClassCastException .

En tu caso, un elenco de Dog a un Animal es un elenco, porque un Dog es un Animal . En general, puede actualizar cada vez que haya una relación is-a entre dos clases.

Downcasting sería algo como esto:

Animal animal = new Dog(); Dog castedDog = (Dog) animal;

Básicamente, lo que estás haciendo es decirle al compilador que sabes cuál es realmente el tipo de tiempo de ejecución del objeto. El compilador permitirá la conversión, pero aún insertará una verificación de cordura de tiempo de ejecución para asegurarse de que la conversión tenga sentido. En este caso, el yeso es posible porque en tiempo de ejecución el animal es en realidad un Dog aunque el tipo de animal estático es Animal .

Sin embargo, si hicieras esto:

Animal animal = new Animal(); Dog notADog = (Dog) animal;

Tendría una ClassCastException . La razón es porque animal tipo de tiempo de ejecución de los Animal es Animal y, por lo tanto, cuando le dices al tiempo de ejecución que realice el lanzamiento, ve que ese animal no es realmente un Dog y arroja una ClassCastException .

Para llamar al método de una superclase, puede hacer super.method() o realizar upcast.

Para llamar al método de una subclase tienes que hacer un downcast. Como se muestra arriba, normalmente arriesga una ClassCastException al hacer esto; sin embargo, puede usar el operador instanceof para verificar el tipo de tiempo de ejecución del objeto antes de realizar el lanzamiento, lo que le permite evitar ClassCastException s:

Animal animal = getAnimal(); // Maybe a Dog? Maybe a Cat? Maybe an Animal? if (animal instanceof Dog) { // Guaranteed to succeed, barring classloader shenanigans Dog castedDog = (Dog) animal; }


Upcasting y Downcasting son una parte importante de Java, que nos permite crear programas complicados usando sintaxis simple, y nos brinda grandes ventajas, como polimorfismo o agrupamiento de diferentes objetos. Java permite que un objeto de un tipo de subclase se trate como un objeto de cualquier tipo de superclase. Esto se llama upcasting. Upcasting se realiza automáticamente, mientras downcasting debe ser hecho manualmente por el programador , y voy a dar mi mejor esfuerzo para explicar por qué es así.

Upcasting y downcasting NO son como lanzar primitivas de una a otra, 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 ser anulado cuando se usa en herencia, a menos que ese método se declare como final o estático .

Puede ver el ejemplo a continuación de cómo getType(); funciona según el tipo de objeto (perro, mascota, perro policía).

Suponer que tienes tres perros

  1. Perro: esta es la súper Clase.
  2. Perro de mascota - Perro de mascota extiende el perro.
  3. Police Dog - Police Dog extiende Pet Dog.

    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 ser anulado cuando se usa en herencia, a menos que ese método se declare como final o estático. (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 dinámicamente enlazados del objeto. Las llamadas a métodos se realizan obteniendo la dirección del método de la tabla de envío del objeto. La tabla de envío es la misma para todos los objetos que pertenecen a la misma clase y, por lo tanto, típicamente 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();

Imprime un Normal Dog

obj2.getType();

Imprime el Pet Dog

obj3.getType();

Imprime Police Dog

Downcasting debe ser hecho por el programador manualmente

Cuando intenta invocar el secretID(); método en obj3 que es PoliceDog object pero referenciado a Dog que es una obj3 en la jerarquía arroja un error ya que obj3 no tiene acceso al método secretId() . Para invocar ese método, debes bajar ese obj3 manualmente a PoliceDog

( (PoliceDog)obj3).secretID();

que imprime ID

De la misma manera que invocar dogName(); método en la clase PetDog necesita obj2 a PetDog ya que obj2 se hace referencia a Dog y no tiene acceso a dogName(); método

( (PetDog)obj2).dogName();

¿Por qué es eso así, que el upcasting es automático, pero downcasting debe ser manual? Bueno, ya ves, upcasting nunca puede fallar. Pero si tienes un grupo de diferentes perros y quieres abatirlos a todos según su tipo, existe la posibilidad de que algunos de estos perros sean de diferentes tipos, es decir, PetDog , PoliceDog y el proceso falle, lanzando ClassCastException .

Esta es la razón por la que necesita bajar sus objetos manualmente si ha referenciado 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 la bajó, sigue siendo la misma, solo los está agrupando para un tipo particular, en este caso Dog


upcasting significa lanzar el objeto a un supertipo, mientras que downcasting significa lanzar a un subtipo.

En Java, la conversión ascendente no es necesaria, ya que se realiza automáticamente. Y generalmente se lo conoce como conversión implícita. Puede especificarlo para que quede claro para los demás.

Por lo tanto, escribiendo

Animal a = (Animal)d;

o

Animal a = d;

conduce exactamente al mismo punto y en ambos casos se ejecutará la callme() de Dog .

Downcasting es necesario porque definiste a objeto como Animal. Actualmente sabes que es un Dog , pero java no tiene garantías de que sea. En realidad, en tiempo de ejecución podría ser diferente y java arrojará una ClassCastException , sucedería eso. Por supuesto, no es el caso de tu ejemplo de muestra. Si no desea callme2() a Animal , java ni siquiera podría compilar la aplicación porque Animal no tiene el método callme2() .

En su ejemplo, no puede alcanzar el código de callme() de Animal de UseAnimlas (porque Dog sobrescribe) a menos que el método sea el siguiente:

class Dog extends Animal { public void callme() { super.callme(); System.out.println("In callme of Dog"); } ... }