Menu
Coddy logo textTech

Upcasting y Downcasting

Parte de la sección Programación Orientada a Objetos del Journey de Java de Coddy. Lección 30 de 87.

En la lección anterior, viste cómo una variable de tipo padre puede contener un objeto hijo: Animal myPet = new Dog(). Esta asignación se denomina upcasting y ocurre automáticamente porque un Dog siempre es un Animal.

La conversión ascendente sube en la jerarquía de herencia. Es implícita y siempre segura:

Dog dog = new Dog();
Animal animal = dog;  // Upcasting - automático

Cuando haces un upcast, solo puedes acceder a los métodos definidos en la clase padre. Los métodos específicos del hijo quedan ocultos, aunque el objeto siga siendo un Dog subyacente.

La conversión descendente va en la dirección opuesta: convierte una referencia al padre de nuevo en un tipo hijo. Esto requiere una conversión explícita porque no siempre es segura:

Animal animal = new Dog();  // Upcasting
Dog dog = (Dog) animal;     // Downcasting - se requiere un cast explícito
dog.bark();                 // Ahora podemos acceder a los métodos de Dog

La conversión a un tipo más específico es arriesgada. Si el objeto no es realmente del tipo al que intentas convertirlo, Java lanza una ClassCastException durante la ejecución:

Animal animal = new Cat();
Dog dog = (Dog) animal;  // ¡Compila, pero falla en tiempo de ejecución!

El compilador no puede detectar este error porque solo ve los tipos declarados. El tipo real del objeto solo se conoce cuando se ejecuta el programa. En la próxima lección, aprenderás a comprobar de forma segura el tipo de un objeto antes de realizar una conversión descendente.

challenge icon

Desafío

Fácil

Construyamos un sistema de reproductor multimedia que demuestre tanto el upcasting como el downcasting en acción. Crearás una jerarquía de tipos multimedia y practicarás la conversión entre referencias de clases padre e hijas.

Organizarás tu código en cuatro archivos:

  • Media.java: Crea la clase base que comparten todos los tipos multimedia. Cada elemento multimedia tiene un campo title (String). Incluye un constructor para inicializarlo, un método getter getTitle() y un método play() que imprime: Playing: [title]
  • Song.java: Crea una clase que extienda Media. Las canciones tienen un campo adicional artist (String). Usa super para la inicialización de la clase padre. Sobrescribe play() para imprimir: Playing song: [title] by [artist]. Añade un método showArtist() que imprime: Artist: [artist]
  • Podcast.java: Crea otra clase que extienda Media. Los podcasts tienen un campo episode (int). Sobrescribe play() para imprimir: Playing podcast: [title] - Episode [episode]. Añade un método showEpisode() que imprime: Episode: [episode]
  • Main.java: Demuestra el upcasting y el downcasting con tus tipos multimedia. Recibirás cuatro entradas: el título de una canción, el nombre de un artista, el título de un podcast y un número de episodio.

    Primero, crea un Song y haz upcasting a una referencia Media. Llama a play() en esta referencia para observar la polimorfía en tiempo de ejecución.

    Después, haz downcasting de esa referencia Media nuevamente a Song y llama a showArtist() para acceder al método específico de la clase hija.

    Luego, crea un Podcast y haz upcasting a una referencia Media. Llama a play() en esta referencia.

    Finalmente, haz downcasting de esa referencia Media nuevamente a Podcast y llama a showEpisode().

Recibirás cuatro entradas: el título de la canción (String), el nombre del artista (String), el título del podcast (String) y el número de episodio (int).

Tu salida debe mostrar cuatro líneas: dos para la canción (su salida de reproducción y la información del artista) y dos para el podcast (su salida de reproducción y la información del episodio). ¡Observa cómo el upcasting te permite tratar diferentes tipos multimedia de manera uniforme, mientras que el downcasting te permite acceder a sus características únicas!

Pruébalo tú mismo

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Leer entradas
        String songTitle = scanner.nextLine();
        String artistName = scanner.nextLine();
        String podcastTitle = scanner.nextLine();
        int episodeNumber = scanner.nextInt();
        
        // TODO: Crea un Song y haz upcast a una referencia Media
        
        // TODO: Llama a play() en la referencia Media (demuestra polimorfismo)
        
        // TODO: Haz downcast de la referencia Media de vuelta a Song
        
        // TODO: Llama a showArtist() en la referencia Song
        
        // TODO: Crea un Podcast y haz upcast a una referencia Media
        
        // TODO: Llama a play() en la referencia Media
        
        // TODO: Haz downcast de la referencia Media de vuelta a Podcast
        
        // TODO: Llama a showEpisode() en la referencia Podcast
    }
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación Orientada a Objetos

Practica por tu cuenta: Compilador de Java online