Foros del Web » Programación para mayores de 30 ;) » Java »

[Ayuda]Upcast y downcast

Estas en el tema de [Ayuda]Upcast y downcast en el foro de Java en Foros del Web. Hola alguien me podria explicar este tema por favor,en todos lados encuentro el mismo ejemplo empleado ejecutivo. Y no encuentro la gracia de disfrazar un ...
  #1 (permalink)  
Antiguo 12/01/2015, 23:18
 
Fecha de Ingreso: noviembre-2014
Mensajes: 50
Antigüedad: 9 años, 11 meses
Puntos: 0
[Ayuda]Upcast y downcast

Hola alguien me podria explicar este tema por favor,en todos lados encuentro el mismo ejemplo empleado ejecutivo.
Y no encuentro la gracia de disfrazar un objeto de otro objeto,cual es el fin?
No entiendo me confunde mucho este concepto
  #2 (permalink)  
Antiguo 13/01/2015, 04:46
Avatar de Xerelo  
Fecha de Ingreso: mayo-2009
Mensajes: 2.175
Antigüedad: 15 años, 5 meses
Puntos: 306
Respuesta: [Ayuda]Upcast y downcast

Un ejecutivo es un empleado, supón que quieres controlar las vacaciones de todos los empleados.

¿Tendrías una List para los empleados y otro para los ejecutivos? Podrías, pero sería mejor solución tener todos en un mismo List. Por ejemplo

List<Empleado> empleados

Cuando añades ejecutivos a ese listado estás haciendo un upcast, ya que estás diciendo que un Ejecutivo se "comporte" como un Empleado. Cuando lo recuperes de esa lista será un Empleado.

¿Qué sucede si quieres ver el sueldo y resulta que los ejecutivos tienen un bono que no tienen los empleados?

Como lo has recuperado de la lista "es" un empleado, no puedes acceder al bono. Ahí entra el downcast, ya que mediante el cast dirías que un Empleado realmente es un Ejecutivo, y por lo tanto ya podrías acceder al bono.

(Ejecutivo) empleados.get(1)

El downcast tiene un peligro, que el hecho de que sea Empleado no significa que sea un ejecutivo, por lo que es algo que debe ser controlado por el código.

Esto es un ejemplo de para qué sirve, pero tiene más usos. Deberías leer sobre polimorfismo.
__________________
Cada vez que solucionas los problemas de alguien que no se esfuerza, piensa en que el día de mañana puede llegar a ser tu compañero de trabajo, o peor, tu jefe.
  #3 (permalink)  
Antiguo 13/01/2015, 11:35
 
Fecha de Ingreso: noviembre-2014
Mensajes: 50
Antigüedad: 9 años, 11 meses
Puntos: 0
Respuesta: [Ayuda]Upcast y downcast

Muchas gracias me quedo un poco claro no tanto.
Pero si se lo que es polimorfismo cuando las clases interpretan un mismo "mensaje" de otra manera.
Por ejemplo implemento las interfaces cada clase puede interpretar cada metodo de una manera distinta.
Código Java:
Ver original
  1. Ejecutivo  eje = new Empleado()
Eso tambien lo vi cuando esta casteo.
Ahi un ejecutivo estaria "disfrazado" de empleado pero tiene ambos metodos de las dos clases?
  #4 (permalink)  
Antiguo 13/01/2015, 12:01
 
Fecha de Ingreso: noviembre-2014
Mensajes: 50
Antigüedad: 9 años, 11 meses
Puntos: 0
Respuesta: [Ayuda]Upcast y downcast

Código Java:
Ver original
  1. Persona p = new Empleado(...);
  2. Empleado e = (Empleado) p

Esas parte de codigo me confunden
  #5 (permalink)  
Antiguo 13/01/2015, 12:49
Avatar de chuidiang
Colaborador
 
Fecha de Ingreso: octubre-2004
Mensajes: 3.774
Antigüedad: 20 años
Puntos: 454
Respuesta: [Ayuda]Upcast y downcast

Hola:

Cuando haces un new de una clase (Empleado), en memoria tienes una clase Empleado.

Puedes guardar esa zona de memoria en una variable de tipo Empleado o en una variable cuyo tipo sea padre de Empleado. Es decir, estas dos cosas, si Persona es padre de Empleado, son válidas

Persona p = new Empleado();
Empleado e = new Empleado();

El problema de guardar un Empleado en una variable de tipo Persona, es que en memoria sigues tieniendo un Empleado, pero no puedes acceder a los métodos propios de Empleado que no tiene Persona. Si Empleado tiene un método unMetodo() que no tiene Persona, no puedes llamarlo de ninguna manera, ya que p.unMetodo() te protestará en compilado.

Como p tiene realmente en memoria un Empleado, la forma de recuperarlo para poder usar todos sus métodos, es hacer el "cast" que has hecho

Empleado e = (Empleado) p;

¿Por qué guardar un Empleado en una variable de tipo Persona?. Porque puedes hacer un método que trate con Persona, llamando por ejemplo a su método getNombre(), estilo este

Código Java:
Ver original
  1. public void escribeNombre(Persona p) {
  2.     System.out.println(p.getNombre());
  3. }

y podrías llamar a este método con una Persona, con un Empleado o incluso con una clase que todavía no existe y que hagas más adelante que sea hija de Persona.

También, como dice Xerelo, puedes hacer una lista de Personas y meter ahí Empleados, Personas o lo que quieras, mezclados.

Se bueno.
__________________
Apuntes Java
Wiki de Programación
  #6 (permalink)  
Antiguo 13/01/2015, 13:39
 
Fecha de Ingreso: noviembre-2014
Mensajes: 50
Antigüedad: 9 años, 11 meses
Puntos: 0
Respuesta: [Ayuda]Upcast y downcast

Pero cual es la ventaja del cast? porque si quiero metodos de clase empleado creo que objeto tipo empleado asi
Código Java:
Ver original
  1. Empleado e = new Empleado()

No entiendo la ventaja de usar cast si quiero usar metodos de empleado creo un objeto de tipo empleado y si quiero un objeto de tipo Persona creo un objeto de tipo Persona no entiendo para que se mezclan esta linea por ejemplo




Código Java:
Ver original
  1. Persona p = new Empleado();

Ahi tengo un objeto de tipo Empleado que tiene los metodos de persona,no?Cual es la ventaja de hacer eso me cuesta mucho entender
  #7 (permalink)  
Antiguo 13/01/2015, 14:17
Avatar de chuidiang
Colaborador
 
Fecha de Ingreso: octubre-2004
Mensajes: 3.774
Antigüedad: 20 años
Puntos: 454
Respuesta: [Ayuda]Upcast y downcast

Hola:

No es habitual hacerlo de forma tan directa, como bien dices, si quieres un empleado, lo guardas en una variable empleado y listo.

Lo mas habitual suele ser tener un "almacen" de Persona en el que metes, mezclados, cosas como Empleado, Supervisor, Jefe, Director, etc, todos ellos que heredan de Persona.

LinkedList<Persona>lista = new LinkedList<>();
lista.add(new Empleado());
lista.add(new Persona());
lista.add(new Director());
...

cuando recorres esa lista y necesitas métodos que todos tienen porque heredas de Persona, no hace falta nada especial.

Código Java:
Ver original
  1. for (Persona p: lista) {
  2.    System.out.println(p.getNombre());
  3. }

Pero imagina que te piden que escribas el sueldo de los empleados y getSueldo() solo lo tienen los empleados. No te queda mas que hacer algo como esto

Código Java:
Ver original
  1. for (Persona p : lista) {
  2.    if (p instanceof Empleado) {
  3.         Empleado e = (Empleado)p;
  4.         System.out.println (e.getSueldo());
  5.    }
  6. }

como ves, se tiene un empleado guardado en una variable de tipo Persona y hay que hacer el cast para poder llamar a getSueld().

Se bueno.
__________________
Apuntes Java
Wiki de Programación
  #8 (permalink)  
Antiguo 13/01/2015, 16:17
 
Fecha de Ingreso: noviembre-2014
Mensajes: 50
Antigüedad: 9 años, 11 meses
Puntos: 0
Respuesta: [Ayuda]Upcast y downcast

Entonces el upcast y el downcast sirven para usar metodos de otras clases,sirve para escribir menos codigo?
siempre cuando entre ellas tenga una relacion de herencian en comun.
Ese es el fin del casteo?
  #9 (permalink)  
Antiguo 13/01/2015, 21:02
Avatar de HackmanC  
Fecha de Ingreso: enero-2008
Ubicación: Guatemala
Mensajes: 1.817
Antigüedad: 16 años, 9 meses
Puntos: 260
Sonrisa Respuesta: [Ayuda]Upcast y downcast

Hola,

Posiblemente

Cita:
Iniciado por tapiadiego335 Ver Mensaje
...Ese es el fin del casteo?
Desde mi punto de vista muy personal, el fin del casteo no es tanto un fin sino mas bien un efecto secundario. Hasta el momento en este hilo se mencionado la herencia, pero no se ha mencionado mucho sobre las interfaces, donde yo creo que es mas evidente el concepto.

Cita:
Iniciado por tapiadiego335 Ver Mensaje
[B]Pero cual es la ventaja del cast? ...
Lo que sucede en ese caso es que es un punto de vista muy simplificado. Lógicamente cuando quieras un nuevo objeto de tipo empleado vas a usar el tipo Empleado para almacenar la referencia. Pero hay momentos donde surge la necesidad de usar este concepto de forma mas compleja.

El ejemplo mas simple que se me ocurre es el siguiente, supongamos que tienes una clase con un método para enviar mensajes:

Código Java:
Ver original
  1. public void enviarMensaje(Transporte transporte, Mensaje mensaje) {
  2.   transaporte.enviar(mensaje);
  3. }

También supongamos que tienes varios transportes, puede ser por email, por mensaje instantáneo, por mensaje subliminal u otros. El método enviarMensaje anterior se encarga de enviar el mensaje por el método que le indiques por Transporte, así que podrías implementar diferentes Transportes.

Código Java:
Ver original
  1. public interface Transporte {
  2.   void enviar(Mensaje mensaje);
  3. }
  4.  
  5. public class TransporteEmail implements Transporte {
  6.   public void enviar(Mensaje mensaje) {
  7.     // enviar por correo ...
  8.   }
  9. }
  10.  
  11. public class TransporteTwitter implements Transporte {
  12.   public void enviar(Mensaje mensaje) {
  13.     // enviar por twitter ...
  14.   }
  15. }
  16.  
  17. public class TransporteSubliminal implements Transporte {
  18.   public void enviar(Mensaje mensaje) {
  19.     // enviar mentalmente ...
  20.   }
  21. }

Y posiblemente la forma de usar el downcast es el siguiente ...

Código Java:
Ver original
  1. ClaseEnviar ce = new ClaseEnviar();
  2. Transporte ts = new TransporteSubliminal();
  3. ce.enviarMensaje(ts, new Mensaje());

Es decir, estás creando una clase TransporteSubliminal, pero el método enviarMensaje solo le interesa que sea un Transporte, el método lo usa como una clase básica que implementa Transporte, esto te permite que puedas cambiar a TransporteFacebook mas adelante sin modificar el código existente, solamente cambiando TransporteSubliminal() por TransporteFacebook().

Adicionalmente no necesitas un método enviarPorTransporteEmail, enviarPorTransporteSubliminal, etc., y de allí saca tus conclusiones de como te puede ser útil y simple poder cambiar el transporte dependiendo de la configuración o el estado de tu aplicación, etc.

Este ejemplo está creado con una interfaz, que puede modificar para que extienda una clase en lugar de una interfaz, para observar todo el efecto claramente. En el caso del upcast el concepto es al contrario, pero no se me ocurre un ejemplo rápidamente en este momento.

Saludos,
  #10 (permalink)  
Antiguo 13/01/2015, 22:19
 
Fecha de Ingreso: noviembre-2014
Mensajes: 50
Antigüedad: 9 años, 11 meses
Puntos: 0
Respuesta: [Ayuda]Upcast y downcast

Muchas gracias por tu tiempo primero.
Tengo una duda el casteo no va asi
"(TipoAcasteear) Objeto que quiero castear"

y esta linea no me queda clara son dos metodos seguidos??
Código Java:
Ver original
  1. transaporte.enviar(mensaje);
  #11 (permalink)  
Antiguo 13/01/2015, 22:59
Avatar de HackmanC  
Fecha de Ingreso: enero-2008
Ubicación: Guatemala
Mensajes: 1.817
Antigüedad: 16 años, 9 meses
Puntos: 260
Sonrisa Respuesta: [Ayuda]Upcast y downcast

Hola,

Cita:
Iniciado por tapiadiego335 Ver Mensaje
Muchas gracias por tu tiempo primero.
Tengo una duda el casteo no va asi
"(TipoAcasteear) Objeto que quiero castear"

y esta linea no me queda clara son dos metodos seguidos??
Código Java:
Ver original
  1. transaporte.enviar(mensaje);
Creo que tendrías que profundizar más en el lenguaje para comprender el concepto y/o la utilidad del downcast en ese caso. En el ejemplo 'transporte' es un parámetro que se envía al método, 'enviar' es un método de la clase o interfaz 'Transporte', que este a su vez recibe un parámetro de tipo Mensaje (aunque el mensaje no es importante en el ejemplo, era simplemente para completar la definición).

Es decir, no son dos métodos seguidos, es un método de un objeto de tipo Transporte, siendo este cualquier objeto que hereda o implementa Transporte, dependiendo si es una clase o una interfaz.

En el caso que yo expuse no era necesario el cast explicito, porque está implicito en una interfaz.

Código Java:
Ver original
  1. Transporte ts = new TransporteSubliminal();

Es lo mismo que:

Código Java:
Ver original
  1. Transporte ts = (Transporte) new TransporteSubliminal();

Saludos,
  #12 (permalink)  
Antiguo 14/01/2015, 03:31
Avatar de Profesor_Falken  
Fecha de Ingreso: agosto-2014
Ubicación: Mountain View
Mensajes: 1.323
Antigüedad: 10 años, 2 meses
Puntos: 182
Respuesta: [Ayuda]Upcast y downcast

Cita:
Entonces el upcast y el downcast sirven para usar metodos de otras clases,sirve para escribir menos codigo?
siempre cuando entre ellas tenga una relacion de herencian en comun.
Ese es el fin del casteo?
Si, pero no exactamente. El polimorfismo permite hacer cosas que no serian posibles (o serian muy muy complicadas) de otra manera.
Te he hecho un ejemplo para que lo estudies que creo que es bastante explicativo:

Código Java:
Ver original
  1. public class TestPolimorfismo {
  2.  
  3.     public static void main(String[] args) {
  4.         List<Animal> animales = Arrays.asList(new Animal[]{new Caballo(), new Humano(), new Paloma(), new Humano(), new Paloma()});
  5.  
  6.         //Hablar (todos lo hacen, luego no hay que preocuparse si no todos son del mismo tipo)
  7.         for (final Animal animal : animales) {
  8.             animal.habla();
  9.         }
  10.  
  11.         //Que vuelen los que pueden!
  12.         for (final Animal animal : animales) {
  13.             if (animal instanceof Ave) {
  14.                 ((Ave) animal).vuela();
  15.             }
  16.         }
  17.     }
  18. }
  19.  
  20. interface Animal {
  21.  
  22.     void habla();
  23. }
  24.  
  25. interface Ave extends Animal {
  26.  
  27.     void vuela();
  28. }
  29.  
  30. class Caballo implements Animal {
  31.  
  32.     @Override
  33.     public void habla() {
  34.         System.out.println("HIIIIJJAAAAAA");
  35.     }
  36. }
  37.  
  38. class Humano implements Animal {
  39.  
  40.     @Override
  41.     public void habla() {
  42.         System.out.println("HOLAQUEASE");
  43.     }
  44. }
  45.  
  46. class Paloma implements Ave {
  47.  
  48.     @Override
  49.     public void habla() {
  50.         System.out.println("PRRRRUP");
  51.     }
  52.  
  53.     @Override
  54.     public void vuela() {
  55.         System.out.println("Paloma vuela y hace PRRRRUP ");
  56.     }
  57. }

Código Salida Consola:
Ver original
  1. HIIIIJJAAAAAA
  2. HOLAQUEASE
  3. PRRRRUP
  4. HOLAQUEASE
  5. PRRRRUP
  6. Paloma vuela y hace PRRRRUP
  7. Paloma vuela y hace PRRRRUP

Un saludo
__________________
If to err is human, then programmers are the most human of us
  #13 (permalink)  
Antiguo 14/01/2015, 11:56
 
Fecha de Ingreso: noviembre-2014
Mensajes: 50
Antigüedad: 9 años, 11 meses
Puntos: 0
Respuesta: [Ayuda]Upcast y downcast

Gracias eso lo entiendo es polimorfismo,el mismo metodo en cada clase cambia su "contenido",lo que no entiendo es Casteo.
  #14 (permalink)  
Antiguo 14/01/2015, 11:59
 
Fecha de Ingreso: noviembre-2014
Mensajes: 50
Antigüedad: 9 años, 11 meses
Puntos: 0
Respuesta: [Ayuda]Upcast y downcast

ah ya entendi "memsaje" y "transporte" son dos parametros pero es lo mismo que hacer esto
Código Java:
Ver original
  1. public void enviarMensaje(Transporte transporte, Mensaje mensaje) {
  2.   enviar(mensaje,trasnporte);
  3. }

Estaria bien eso?
  #15 (permalink)  
Antiguo 14/01/2015, 14:06
Avatar de HackmanC  
Fecha de Ingreso: enero-2008
Ubicación: Guatemala
Mensajes: 1.817
Antigüedad: 16 años, 9 meses
Puntos: 260
Sonrisa Respuesta: [Ayuda]Upcast y downcast

Hola,

Cita:
Iniciado por tapiadiego335 Ver Mensaje
ah ya entendi "memsaje" y "transporte" son dos parametros pero es lo mismo que hacer esto
Código Java:
Ver original
  1. public void enviarMensaje(Transporte transporte, Mensaje mensaje) {
  2.   enviar(mensaje,trasnporte);
  3. }

Estaria bien eso?
Estaría bien, pero no es lo mismo, en el ejemplo que yo mostré estaría llamando al método enviar() del objeto transporte, en tu ejemplo estarías llamando a un método llamado enviar() que debería estar definido en la misma clase que enviarMensaje, si no existiera ese método el compilador generaría un error.

Ahora bien, aunque puedo estar equivocado, creo que te hace falta profundizar un poco mas en el lenguaje Java antes de ponerte a pensar en Cast. Es decir, primero pensaste que eran dos métodos seguidos (cosa que no se puede hacer en Java, de la forma como está escrito el ejemplo), ahora piensas que al quitar el objeto transporte estarías llamando al mismo método, y que es lo mismo cuando realmente son dos cosas completamente diferentes.

Y en todo eso no hay nada de casteo es puro lenguaje Java, bastante básico por cierto. Es decir, no hemos llegado a la parte complicada (que sería el Cast) y ya tienes muchas dudas sobre los parámetros de un método, que es la parte básica que deberías conocer previamente.

Posiblemente te resulte mas simple el ejemplo de Profesor_Falken, donde evidentemente hace casteo, pero normalmente el concepto va de la mano con el polimorfismo y otros patrones de diseño.

Saludos,

Última edición por HackmanC; 14/01/2015 a las 14:19

Etiquetas: Ninguno
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 17:42.