Sobrescrita de Método (@Override)
Parte da seção Programação Orientada a Objetos do Journey de Java da Coddy. Lição 22 de 87.
Method overriding permite que uma subclasse forneça sua própria implementação de um method que já está definido em sua classe parent. É assim que as classes filhas personalizam o behavior herdado para atender às suas necessidades específicas.
Quando você faz overriding de um method, a versão da subclasse substitui completamente a versão do parent para object dessa subclasse. O method deve ter o mesmo nome e os mesmos parâmetros que o method do parent, e um tipo de retorno que seja igual ao do parent (ou um subtipo dele):
public class Animal {
public void makeSound() {
System.out.println("Some generic sound");
}
}
public class Dog extends Animal {
@Override
public void makeSound() {
System.out.println("Woof!");
}
}
public class Cat extends Animal {
@Override
public void makeSound() {
System.out.println("Meow!");
}
}A @Override annotation informa ao compiler que você pretende fazer overriding de um parent method. Embora opcional, ela é altamente recomendada, porque o compiler detectará erros se você acidentalmente escrever o nome do method incorretamente ou usar parâmetros errados:
@Override
public void makeSound() { } // Correto - o compilador verifica isto
public void makesound() { } // Erro de digitação! Cria um novo método em vez de sobrescreverQuando você chama um método sobrescrito, Java executa a versão que pertence ao tipo real do objeto:
Dog dog = new Dog();
dog.makeSound(); // Saída: Woof!
Cat cat = new Cat();
cat.makeSound(); // Saída: Meow!Lembre-se da lição anterior de que você pode usar super.methodName() dentro de um método substituído se ainda quiser incluir o comportamento do parent junto com seu novo código.
Desafio
FácilVamos criar um sistema de notificações que demonstra como as subclasses podem substituir métodos da classe parent para fornecer seu próprio comportamento especializado. Você verá como a anotação @Override ajuda a detectar erros e como cada subclasse pode personalizar os métodos herdados.
Você criará três arquivos para organizar seu código:
Notification.java: Crie a classe parent que representa uma notification generic. Ela deve ter:- Um field private para
message(String) - Um constructor que accepts a message
- Um method
getMessage()que retorna a message - Um method
send()que prints:Sending notification: [message]
- Um field private para
EmailNotification.java: Crie uma subclasse que extends Notification e personaliza como as notifications são enviadas por email:- Um field private para o endereço de email do
recipient(String) - Um constructor que recebe tanto a message quanto o recipient, usando
super(message)para a parte da classe parent - Faça o overriding do method
send()usando a anotação@Overridepara prints:Emailing [recipient]: [message]
- Um field private para o endereço de email do
Main.java: Demonstre como o mesmo nome de method produz um behavior diferente dependendo do tipo de object. Você receberá dois inputs: uma message e um endereço de email. Crie uma Notification regular e uma EmailNotification com a mesma message e, em seguida, faça umsend()em cada uma para ver os diferentes outputs.
Você receberá dois inputs: a message (String) e o endereço de email do recipient (String).
Seu output deve mostrar duas linhas — primeiro a partir do method send() da classe parent e depois a partir da versão overriding em EmailNotification. Isso demonstra como o overriding de methods permite que as subclasses substituam o behavior herdado por sua própria implementaçã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 message = scanner.nextLine();
String recipient = scanner.nextLine();
// TODO: Create a Notification object with the message
// TODO: Create an EmailNotification object with the message and recipient
// TODO: Call send() on the Notification object
// TODO: Call send() on the EmailNotification object
}
}
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
1Fundamentos de POO
Arquivos ExternosIntrodução à POOClasses vs ObjetosA Palavra-chave thisMétodosCampos (Atributos)Método ConstrutorSobrecarga de ConstrutorRecapitulação - Calculadora Simples4Herança
Herança Básica (extends)A Palavra-chave superSobrescrita de Método (@Override)Encadeamento de ConstrutoresA Classe ObjectHerança Simples e MultinívelPor que não há Herança Múltipla de ClassesRecapitulação - Hierarquia de Funcionários7Métodos Especiais e a Classe Object
Método toString()equals() e hashCode()Método clone()compareTo() e ComparableInterface ComparatorRecapitulação - Ordenação Personalizada2Modificadores de Acesso e Encapsulamento
Visão Geral dos Níveis de AcessoMétodos Getter e SetterOcultação de InformaçõesA Palavra-chave finalRecapitulação - Gerenciador de Conta Bancária5Polimorfismo
Fundamentos de Sobrecarga de MétodosSobrescrita de Métodos (Tempo de Execução)Upcasting e DowncastingO Operador instanceofClasses e Métodos AbstratosRecapitulação - Calculadora de Formas8Conceitos Avançados de OOP
Composição vs HerançaAgregação vs ComposiçãoClasses Internas, Aninhadas e AnônimasEnums e Métodos de EnumRecords (Java 16+)Classes Seladas (Java 17+)11Padrões de Projeto Parte 1
Introdução aos Padrões de ProjetoPadrão SingletonPadrão FactoryPadrão BuilderPadrão ObserverPadrão Strategy3Propriedades de Classe e Membros Estáticos
Variáveis de Instância vs EstáticasMétodos EstáticosBlocos EstáticosConstantes (static final)Recapitulação - Contador e Utilitário6Interfaces e Classes Abstratas
Introdução às InterfacesImplementando InterfacesImplementação de Múltiplas InterfacesDefault e Static em InterfacesClasses Abstratas vs InterfacesInterfaces FuncionaisRecapitulação - Sistema de Pagamento9Generics
Introdução a GenericsClasses GenéricasMétodos GenéricosParâmetros de Tipos DelimitadosWildcards (?, extends, super)Recapitulação - Container Genérico12Padrões de Projeto Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão CompositePadrão IteratorPratique por conta própria: Compilador de Java online