Sobrescritura de métodos (@Override)
Parte de la sección Programación Orientada a Objetos del Journey de Java de Coddy. Lección 22 de 87.
La sobrescritura de métodos permite que una subclase proporcione su propia implementación de un método que ya está definido en su clase padre. Así es como las clases hijas personalizan el comportamiento heredado para adaptarlo a sus necesidades específicas.
Cuando sobrescribes un método, la versión de la subclase reemplaza por completo la versión de la clase padre para los objetos de esa subclase. El método debe tener el mismo nombre y los mismos parámetros que el método de la clase padre, y un tipo de retorno que sea igual o un subtipo del de la clase padre:
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!");
}
}La anotación @Override indica al compilador que pretendes sobrescribir un método de la clase padre. Aunque es opcional, se recomienda encarecidamente porque el compilador detectará errores si escribes accidentalmente de forma incorrecta el nombre del método o utilizas parámetros incorrectos:
@Override
public void makeSound() { } // Correcto - el compilador verifica esto
public void makesound() { } // ¡Typo! Crea un nuevo método en lugar de sobrescribirCuando llamas a un método sobrescrito, Java ejecuta la versión que pertenece al tipo real del objeto:
Dog dog = new Dog();
dog.makeSound(); // Salida: Woof!
Cat cat = new Cat();
cat.makeSound(); // Salida: Meow!Recuerda de la lección anterior que puedes usar super.methodName() dentro de un método sobrescrito si aún quieres incluir el comportamiento del padre junto con tu nuevo código.
Desafío
FácilConstruyamos un sistema de notificaciones que demuestre cómo las subclases pueden sobrescribir los métodos de la clase padre para proporcionar su propio comportamiento especializado. Verás cómo la anotación @Override ayuda a detectar errores y cómo cada subclase puede personalizar los métodos heredados.
Crearás tres archivos para organizar tu código:
Notification.java: Crea la clase padre que representa una notificación genérica. Debe tener:- Un campo privado para el
message(String) - Un constructor que acepte el mensaje
- Un método
getMessage()que devuelva el mensaje - Un método
send()que imprima:Sending notification: [message]
- Un campo privado para el
EmailNotification.java: Crea una subclase que extienda Notification y personalice la forma en que se envían las notificaciones por correo electrónico:- Un campo privado para la dirección de correo electrónico del
recipient(String) - Un constructor que reciba tanto el mensaje como el destinatario, usando
super(message)para la parte correspondiente a la clase padre - Sobrescribe el método
send()usando la anotación@Overridepara imprimir:Emailing [recipient]: [message]
- Un campo privado para la dirección de correo electrónico del
Main.java: Demuestra cómo el mismo nombre de método produce un comportamiento diferente dependiendo del tipo de objeto. Recibirás dos entradas: un mensaje y una dirección de correo electrónico. Crea una Notification normal y una EmailNotification con el mismo mensaje; después, llama asend()en cada una para ver las diferentes salidas.
Recibirás dos entradas: el mensaje (String) y la dirección de correo electrónico del destinatario (String).
Tu salida debe mostrar dos líneas: primero la del método send() de la clase padre y después la de la versión sobrescrita en EmailNotification. Esto demuestra cómo la sobrescritura de métodos permite a las subclases reemplazar el comportamiento heredado con su propia implementación.
Pruébalo tú mismo
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Leer las 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 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
1Fundamentos de OOP
Archivos externosIntroducción a la OOPClases vs. ObjetosLa palabra clave thisMétodosCampos (Atributos)Método constructorSobrecarga de constructoresResumen - Calculadora simple4Herencia
Herencia básica (extends)La palabra clave superSobrescritura de métodos (@Override)Encadenamiento de constructoresLa clase ObjectHerencia simple y multinivelPor qué no hay herencia múltiple de clasesResumen - Jerarquía de empleados7Métodos especiales y la clase Object
Método toString()equals() y hashCode()Método clone()compareTo() y ComparableInterfaz ComparatorResumen - Ordenamiento personalizado2Modificadores de acceso y encapsulamiento
Visión general de los niveles de accesoMétodos Getter y SetterOcultamiento de informaciónLa palabra clave finalResumen - Gestor de cuentas bancarias5Polimorfismo
Fundamentos de sobrecarga de métodosSobrescritura de métodos (tiempo de ejecución)Upcasting y DowncastingEl operador instanceofClases y métodos abstractosResumen - Calculadora de figuras8Conceptos avanzados de POO
Composición vs. HerenciaAgregación vs. ComposiciónClases internas, anidadas y anónimasEnums y métodos de EnumRecords (Java 16+)Clases selladas (Java 17+)11Patrones de diseño - Parte 1
Introducción a los patrones de diseñoPatrón SingletonPatrón FactoryPatrón BuilderPatrón ObserverPatrón Strategy3Propiedades de clase y miembros estáticos
Variables de instancia vs. estáticasMétodos estáticosBloques estáticosConstantes (static final)Repaso - Contador y utilidad6Interfaces y Clases Abstractas
Introducción a las InterfacesImplementación de InterfacesImplementación de Múltiples InterfacesMétodos Default y Static en InterfacesClases Abstractas vs InterfacesInterfaces FuncionalesResumen - Sistema de Pagos9Genéricos
Introducción a los genéricosClases genéricasMétodos genéricosParámetros de tipo delimitadosComodines (?, extends, super)Resumen - Contenedor genérico12Patrones de diseño Parte 2
Patrón CommandPatrón AdapterPatrón DecoratorPatrón Template MethodPatrón StatePatrón CompositePatrón IteratorPractica por tu cuenta: Compilador de Java online