Menu
Coddy logo textTech

Upcasting e Downcasting

Parte da seção Programação Orientada a Objetos do Journey de Java da Coddy. Lição 30 de 87.

Na lição anterior, você viu como uma variável do tipo pai pode conter um objeto filho: Animal myPet = new Dog(). Essa atribuição é chamada de upcasting e acontece automaticamente porque um Dog é sempre um Animal.

Upcasting sobe na hierarquia de herança. É implícito e sempre seguro:

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

Ao fazer upcasting, você só pode acessar métodos definidos na classe pai. Os métodos específicos da classe filha ficam ocultos, embora o objeto ainda seja um Dog internamente.

Downcasting segue na direção oposta, convertendo uma referência ao tipo pai de volta para um tipo filho. Isso exige uma conversão explícita porque nem sempre é seguro:

Animal animal = new Dog();  // Upcasting
Dog dog = (Dog) animal;     // Downcasting - cast explícito necessário
dog.bark();                 // Agora podemos acessar os métodos de Dog

Fazer downcasting é arriscado. Se o objeto não for realmente do tipo para o qual você está convertendo, o Java lançará uma ClassCastException em tempo de execução:

Animal animal = new Cat();
Dog dog = (Dog) animal;  // Compila, mas falha em tempo de execução!

O compilador não consegue detectar esse erro porque ele vê apenas os tipos declarados. O tipo real do objeto só é conhecido quando o programa é executado. Na próxima lição, você aprenderá a verificar com segurança o tipo de um objeto antes de fazer o downcast.

challenge icon

Desafio

Fácil

Vamos criar um sistema de reprodução de mídia que demonstra tanto upcasting quanto downcasting na prática. Você criará uma hierarquia de tipos de mídia e praticará a conversão entre referências de pai e de filho.

Você organizará seu código em quatro arquivos:

  • Media.java: Crie a classe base compartilhada por todos os tipos de mídia. Cada item de mídia possui um campo title (String). Inclua um construtor para inicializá-lo, um método getter getTitle() e um método play() que imprime: Playing: [title]
  • Song.java: Crie uma classe que estenda Media. As músicas possuem um campo adicional artist (String). Use super para a inicialização da classe pai. Substitua play() para imprimir: Playing song: [title] by [artist]. Adicione um método showArtist() que imprime: Artist: [artist]
  • Podcast.java: Crie outra classe que estenda Media. Os podcasts possuem um campo episode (int). Substitua play() para imprimir: Playing podcast: [title] - Episode [episode]. Adicione um método showEpisode() que imprime: Episode: [episode]
  • Main.java: Demonstre upcasting e downcasting com seus tipos de mídia. Você receberá quatro entradas: o título de uma música, o nome de um artista, o título de um podcast e um número de episódio.

    Primeiro, crie um Song e faça o upcasting para uma referência Media. Chame play() nessa referência para observar o polimorfismo em tempo de execução.

    Em seguida, faça o downcasting dessa referência Media de volta para Song e chame showArtist() para acessar o método específico da classe filha.

    Depois, crie um Podcast e faça o upcasting para uma referência Media. Chame play() nessa referência.

    Por fim, faça o downcasting dessa referência Media de volta para Podcast e chame showEpisode().

Você receberá quatro entradas: o título da música (String), o nome do artista (String), o título do podcast (String) e o número do episódio (int).

Sua saída deve mostrar quatro linhas — duas para a música (a saída de reprodução e as informações do artista) e duas para o podcast (a saída de reprodução e as informações do episódio). Observe como o upcasting permite tratar diferentes tipos de mídia de maneira uniforme, enquanto o downcasting permite acessar seus recursos exclusivos!

Experimente você mesmo

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Ler entradas
        String songTitle = scanner.nextLine();
        String artistName = scanner.nextLine();
        String podcastTitle = scanner.nextLine();
        int episodeNumber = scanner.nextInt();
        
        // TODO: Crie um Song e faça upcast para uma referência Media
        
        // TODO: Chame play() na referência Media (demonstra polimorfismo)
        
        // TODO: Faça downcast da referência Media de volta para Song
        
        // TODO: Chame showArtist() na referência Song
        
        // TODO: Crie um Podcast e faça upcast para uma referência Media
        
        // TODO: Chame play() na referência Media
        
        // TODO: Faça downcast da referência Media de volta para Podcast
        
        // TODO: Chame showEpisode() na referência Podcast
    }
}
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação Orientada a Objetos

Pratique por conta própria: Compilador de Java online