Sobrescritura de métodos
Parte de la sección Programación Orientada a Objetos del Journey de Dart de Coddy. Lección 38 de 110.
La sobrescritura de métodos ocurre cuando una clase hija proporciona su propia implementación de un método que ya existe en la clase parent. Esto permite que las subclases personalicen el comportamiento heredado mientras mantienen la misma firma del método.
Cuando defines un método en una clase hija con el mismo nombre y los mismos parámetros que uno de la clase padre, la versión de la clase hija toma el control:
class Animal {
String name;
Animal(this.name);
void speak() {
print('$name makes a sound');
}
}
class Dog extends Animal {
Dog(String name) : super(name);
void speak() {
print('$name barks: Woof!');
}
}
void main() {
var animal = Animal('Generic');
var dog = Dog('Buddy');
animal.speak(); // Generic hace un sonido
dog.speak(); // Buddy ladra: ¡Guau!
}Cuando llamas a speak() en una instancia de Dog, Dart ejecuta la versión de Dog, no la de Animal. La clase hija ha sobrescrito el método de la clase padre.
También puedes combinar la sobrescritura con super para ampliar, en lugar de reemplazar, el comportamiento de parent:
class Cat extends Animal {
Cat(String name) : super(name);
void speak() {
super.speak(); // Llama primero a la versión del padre
print('$name also purrs');
}
}Este patrón te permite basarte en una funcionalidad existente. La regla clave es sencilla: el mismo nombre de método y los mismos parámetros en la clase hija reemplazan la implementación de la clase padre cuando se llama en instancias de la clase hija.
Desafío
FácilConstruyamos un sistema de notificaciones que demuestre cómo las clases hijas pueden sobrescribir métodos de las clases padre para personalizar el comportamiento. Crearás diferentes tipos de notificaciones que entregarán mensajes de su propia manera única.
Organizarás tu código en dos archivos:
notification.dart: Define aquí tu jerarquía de notificaciones:- Una clase
Notification(la clase padre) con unString titley unString message. Incluye un constructor que reciba ambos valores y un métodosend()que imprimaNotification: [title] - [message] - Una clase
EmailNotificationque extiendaNotificationy agregue una propiedadString recipient. Sobrescribe el métodosend()para imprimirSending email to [recipient]: [title] - [message] - Una clase
PushNotificationque extiendaNotificationy agregue una propiedadString deviceId. Sobrescribe el métodosend()para llamar primero al métodosend()de la clase padre usandosupery, después, imprimirPushed to device: [deviceId]en la línea siguiente
- Una clase
main.dart: Importa tu archivo de notificaciones y demuestra la sobrescritura de métodos en acción:- Crea una
Notificationbase con el título'Alert'y el mensaje'System update available' - Llama a su método
send() - Imprime una línea vacía
- Crea una
EmailNotificationcon el título'Welcome', el mensaje'Thanks for signing up!'y el destinatario'user@example.com' - Llama a su método
send() - Imprime una línea vacía
- Crea una
PushNotificationcon el título'Reminder', el mensaje'Meeting in 10 minutes'y el deviceId'DEVICE-001' - Llama a su método
send()
- Crea una
Observa cómo EmailNotification reemplaza por completo el comportamiento de la clase padre, mientras que PushNotification lo extiende llamando primero a super.send(). Ambos enfoques son formas válidas de sobrescribir métodos, según tus necesidades.
Salida esperada:
Notification: Alert - System update available
Sending email to user@example.com: Welcome - Thanks for signing up!
Notification: Reminder - Meeting in 10 minutes
Pushed to device: DEVICE-001Pruébalo tú mismo
import 'notification.dart';
void main() {
// TODO: Create a base Notification with title 'Alert' and message 'System update available'
// Llama a su método send()
// TODO: Imprime una línea vacía
// TODO: Crea un EmailNotification con:
// - title: 'Welcome'
// - message: 'Thanks for signing up!'
// - recipient: 'user@example.com'
// Llama a su método send()
// TODO: Imprime una línea vacía
// TODO: Crea un PushNotification con:
// - title: 'Reminder'
// - message: 'Meeting in 10 minutes'
// - deviceId: 'DEVICE-001'
// Llama a su método send()
}
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 POO
Archivos externosLibrerías e importacionesIntroducción a la POOClases vs. ObjetosLa palabra clave thisMétodosVariables de instanciaConceptos básicos de constructoresResumen - Calculadora sencilla4Seguridad de nulos
Introducción a la seguridad de nulosNulables vs No nulablesLos operadores ? y !Palabra clave Late y Null SafetyOperadores Null-awareNull Safety en clasesResumen - Sistema de perfil de usuario7Clases abstractas e interfaces
Clases abstractasMétodos abstractosInterfaces en DartInterfaces implícitasImplementar vs. ExtenderInterfaces múltiplesRepaso - Calculadora de figuras10Colecciones y Genéricos
Visión general de List, Set y MapColecciones con seguridad de tiposClases genéricasMétodos genéricosRestricciones genéricasIterable e IteratorResumen - Almacenamiento genérico2Constructores en Dart
Constructor por defectoConstructores nombradosListas de inicializaciónConstructores constantesConstructores de fábricaConstructores de redireccionamientoResumen - Constructor de formas5Encapsulamiento
Miembros públicos vs. privadosLa convención del prefijo _Privacidad a nivel de libreríaProfundidad en Getters y SettersOcultamiento de informaciónResumen - Registros de estudiantes8Mixins
Introducción a los MixinsCreación de MixinsUso de múltiples MixinsPalabra clave on en MixinsMixin vs HerenciaMixin vs InterfazResumen - Sistema Animal11Métodos especiales
Sobrescritura de toString()Sobrescritura de hashCode y ==Interfaz ComparableMétodo call()Sobrescritura de noSuchMethodResumen - Colección personalizada14Patrones de diseño Parte 1
Introducción a los patrones de diseñoPatrón SingletonPatrón FactoryPatrón ObserverPatrón Strategy3Propiedades de clase
Miembros de instancia vs. estáticosCampos Final y ConstVariables LateMétodos y campos estáticosGetters y SettersResumen - Gestor de cuentas bancarias6Herencia
Herencia básicaLa palabra clave superSobrescritura de métodosLa anotación @overrideLa palabra clave final en clasesConstructores y herenciaResumen - Jerarquía de empleados9Polimorfismo
Fundamentos del polimorfismoPolimorfismo mediante interfacesComprobación de tipos en tiempo de ejecuciónLos operadores is y asPalabra clave covariantResumen - Procesador de pagos12POO Asíncrona
Futures y async/awaitFundamentos de StreamsStream ControllersConstructores asíncronosAsincronía en métodos de claseRepaso - Data Fetcher15Patrones de diseño Parte 2
Patrón CommandPatrón AdapterPatrón DecoratorPatrón Template MethodPatrón StatePatrón CompositePatrón RepositoryPractica por tu cuenta: Compilador de Dart online