Da trilha de Java Este conceito ainda não saiu como card do dia. ir para o card de hoje

Java POO Intermediário

Polimorfismo

Polimorfismo é a capacidade de um objeto ser referenciado por diferentes tipos, permitindo que uma mesma chamada de método produza comportamentos distintos dependendo do objeto real. Em Java, isso é possível porque uma variável de um tipo superclasse pode referenciar objetos de subclasses.

O despacho dinâmico (dynamic dispatch) é o mecanismo pelo qual a JVM decide, em tempo de execução, qual implementação do método será executada, baseada no tipo real do objeto, e não no tipo da variável. Isso permite escrever código genérico que funciona com qualquer subclasse.

Para verificar o tipo real de um objeto, usamos instanceof. Desde Java 16, o pattern matching para instanceof permite declarar uma variável já convertida no mesmo comando, eliminando a necessidade de casting explícito. Quando precisamos acessar membros específicos de uma subclasse, podemos fazer casting explícito, mas isso só é seguro se o objeto for realmente daquele tipo.

Pontos-chave

  • Uma referência de superclasse pode apontar para objetos de qualquer subclasse.
  • O método executado é escolhido em tempo de execução pelo tipo real do objeto (despacho dinâmico).
  • instanceof com pattern (Java 16+) permite testar e converter em uma única expressão.
  • Casting explícito é necessário para acessar membros específicos da subclasse, mas pode lançar ClassCastException se o tipo estiver errado.
  • Use @Override para garantir que você está sobrescrevendo corretamente um método da superclasse.
PolimorfismoExemplo.java
// Exemplo de polimorfismo em Java
abstract class Animal {
    abstract void emitirSom();
}

class Cachorro extends Animal {
    @Override
    void emitirSom() {
        System.out.println("Au au!");
    }
    void abanarRabo() {
        System.out.println("Cachorro abanando o rabo...");
    }
}

class Gato extends Animal {
    @Override
    void emitirSom() {
        System.out.println("Miau!");
    }
}

public class PolimorfismoExemplo {
    public static void main(String[] args) {
        // Referência de superclasse apontando para objetos de subclasses
        Animal a1 = new Cachorro();
        Animal a2 = new Gato();

        // Despacho dinâmico: o método chamado depende do tipo real
        a1.emitirSom(); // Au au!
        a2.emitirSom(); // Miau!

        // instanceof com pattern (Java 16+)
        if (a1 instanceof Cachorro c) {
            c.abanarRabo(); // método específico de Cachorro
        }

        // Casting explícito (seguro após verificação)
        if (a2 instanceof Gato) {
            Gato g = (Gato) a2;
            g.emitirSom(); // Miau!
        }
    }
}

Exercícios

  1. 1
    Fácil

    Formas geométricas polimórficas

    Crie uma hierarquia de classes para representar formas geométricas. A superclasse Forma deve ter um método area() que retorna double. As subclasses Circulo e Retangulo devem implementar area() com as fórmulas corretas. No main, crie um array de Forma com um círculo de raio 2.0 e um retângulo de base 3.0 e altura 4.0. Percorra o array e imprima a área de cada forma.

    Resolver
  2. 2
    Médio

    Sistema de pagamentos com instanceof pattern

    Crie uma hierarquia de pagamentos: Pagamento (abstrata) com método processar(). As subclasses CartaoCredito e Boleto devem implementar processar() imprimindo mensagens específicas. Além disso, CartaoCredito tem um método autorizar() e Boleto tem um método gerarCodigoBarras(). No main, crie uma lista de Pagamento com um cartão e um boleto. Percorra a lista, chame processar() e, usando instanceof com pattern, chame o método específico de cada tipo.

    Resolver
  3. 3
    Desafio

    Processador de arquivos polimórfico com casting seguro

    Crie uma hierarquia para processar diferentes tipos de arquivos: Arquivo (abstrata) com método processar(). As subclasses Texto, Imagem e Video devem implementar processar() com mensagens específicas. Texto tem extrairPalavras(), Imagem tem redimensionar(), Video tem reproduzir(). No main, crie uma lista de Arquivo com instâncias variadas. Percorra a lista, chame processar() e, usando instanceof com pattern, chame o método específico de cada tipo. Além disso, demonstre um casting explícito seguro e um casting que lançaria ClassCastException (capture a exceção e imprima uma mensagem).

    Resolver

Continue estudando