Menu
Coddy logo textTech

Sobrescrita de Métodos (Tempo de Execução)

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

Enquanto a sobrecarga de método é resolvida em tempo de compilação, a sobrescrita de método demonstra polimorfismo de tempo de execução. Aqui, o Java decide qual método executar quando o programa está realmente em execução, com base no tipo real do objeto, em vez do tipo declarado da variável.

Você aprendeu sobre a sobrescrita de métodos no capítulo sobre Herança. O que a torna polimórfica é como o Java a gerencia quando uma referência de pai aponta para um objeto de filho:

public class Animal {
    public void speak() {
        System.out.println("Some sound");
    }
}

public class Dog extends Animal {
    @Override
    public void speak() {
        System.out.println("Bark!");
    }
}

public class Cat extends Animal {
    @Override
    public void speak() {
        System.out.println("Meow!");
    }
}

Agora observe o que acontece quando usamos referências do tipo pai:

Animal myPet = new Dog();
myPet.speak();  // Saída: Bark!

myPet = new Cat();
myPet.speak();  // Saída: Meow!

Embora myPet seja declarado como Animal, o Java chama o método sobrescrito com base no tipo real do objeto em tempo de execução. Isso é chamado de despacho dinâmico de métodos. A JVM olha para o que o objeto realmente é, não para o que a variável diz que ele é.

Isso permite padrões poderosos, como o processamento uniforme de diferentes objetos:

Animal[] pets = {new Dog(), new Cat(), new Dog()};
for (Animal pet : pets) {
    pet.speak();  // Cada um chama sua própria versão
}

O polimorfismo em tempo de execução permite que você escreva código flexível que funciona com tipos pai, enquanto usa automaticamente o comportamento correto do filho.

challenge icon

Desafio

Fácil

Vamos criar um sistema de notificações que demonstra o polimorfismo em tempo de execução na prática. Você criará uma hierarquia de tipos de notificação em que a mesma chamada de método produz diferentes saídas dependendo do tipo real do objeto em tempo de execução.

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

  • Notification.java: Crie a classe base compartilhada por todas as notificações. Toda notificação tem um campo recipient (String). Inclua um construtor para inicializá-lo, um método getter e um método send() que imprime: Sending notification to [recipient]
  • EmailNotification.java: Crie uma classe que estenda Notification. As notificações por e-mail adicionam um campo subject. Use super para a inicialização da classe pai. Substitua o método send() para imprimir: Emailing [recipient]: [subject]
  • SMSNotification.java: Crie outra classe que estenda Notification. As notificações por SMS adicionam um campo phoneNumber. Substitua send() para imprimir: Texting [phoneNumber] for [recipient]
  • Main.java: É aqui que o polimorfismo em tempo de execução se destaca! Você receberá três entradas: um nome de destinatário, um assunto de e-mail e um número de telefone. Crie um array de referências a Notification contendo três objetos nesta ordem: uma Notification base, uma EmailNotification e uma SMSNotification (todas usando o mesmo destinatário). Em seguida, percorra o array e chame send() em cada elemento. Observe como o Java chama automaticamente a versão substituída correta com base no que cada objeto realmente é!

Você receberá três entradas: o nome do destinatário (String), o assunto do e-mail (String) e o número de telefone (String).

Sua saída deve mostrar três linhas — cada chamada de send() produz uma saída diferente, mesmo que você esteja chamando o mesmo método em referências a Notification. Isso é o despacho dinâmico de métodos em ação!

Experimente você mesmo

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Ler as entradas
        String recipient = scanner.nextLine();
        String subject = scanner.nextLine();
        String phoneNumber = scanner.nextLine();
        
        // TODO: Criar um array de referências Notification com 3 elementos
        // O array deve conter (nesta ordem):
        // 1. Um objeto Notification base
        // 2. Um objeto EmailNotification
        // 3. Um objeto SMSNotification
        // Todos usando o mesmo recipient
        
        // TODO: Percorrer o array e chamar send() em cada elemento
        // Isso demonstra o polimorfismo em tempo de execução!
    }
}
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