Palabra clave on en Mixins
Parte de la sección Programación Orientada a Objetos del Journey de Dart de Coddy — lección 53 de 110.
A veces, un mixin necesita usar métodos o propiedades de la clase en la que se mezcla. La palabra clave on te permite restringir un mixin para que solo se use con clases que extienden un tipo específico.
class Animal {
String name;
Animal(this.name);
void breathe() => print('$name is breathing');
}
mixin Swimming on Animal {
void swim() {
print('$name is swimming'); // Puede acceder a 'name' desde Animal
breathe(); // Puede llamar a los métodos de Animal
}
}
class Fish extends Animal with Swimming {
Fish(String name) : super(name);
}La declaración on Animal significa que este mixin solo puede aplicarse a clases que extiendan Animal. Esto garantiza que el mixin tenga acceso a los miembros de Animal. Sin on, el mixin no sabría que name o breathe() existen.
Si intentas usar un mixin restringido en una clase incompatible, Dart te da un error en tiempo de compilación:
class Robot with Swimming {} // ¡Error! Robot no extiende AnimalEsta restricción es útil cuando la funcionalidad de tu mixin depende de capacidades específicas de una clase base. Crea un contrato más seguro: el mixin promete cierto comportamiento, pero solo cuando tiene la base que necesita para funcionar correctamente.
Desafío
FácilVamos a construir un sistema de vehículos que demuestre cómo la palabra clave on restringe los mixins para que funcionen solo con clases base específicas. Crearás un mixin que añade la funcionalidad de turbo boost, pero solo podrá ser utilizado por clases que extiendan una clase base Vehicle.
Organizarás tu código en dos archivos:
vehicles.dart: Define aquí tu clase base, el mixin restringido y los tipos de vehículos:- Una clase
Vehiclecon una propiedadString modely una propiedadint speed. Incluye un constructor que reciba ambos valores. Añade un métodoaccelerate()que imprima'$model accelerating to $speed km/h' - Un mixin
TurboBoostrestringido aVehicleusando la palabra claveon. Este mixin debe tener un métodoactivateTurbo()que imprima'$model TURBO ACTIVATED!'y luego llame aaccelerate()(ambos accesibles debido a la restricciónon Vehicle) - Una clase
SportsCarque extiendaVehicley use el mixinTurboBoost. Añade una propiedadString color. El constructor debe recibir model, speed y color. Incluye un métodoshowOff()que imprima'$color $model ready to race!'
- Una clase
main.dart: Importa tu archivo de vehículos y demuestra cómo funciona el mixin restringido:- Crea un
SportsCarcon model'Ferrari', speed320y color'Red' - Llama a
showOff() - Llama a
activateTurbo()
- Crea un
El mixin TurboBoost puede acceder a model y llamar a accelerate() porque la declaración on Vehicle garantiza que solo se mezclará en clases que extiendan Vehicle. Esto crea un contrato seguro donde el mixin sabe exactamente qué capacidades están disponibles.
Salida esperada:
Red Ferrari ready to race!
Ferrari TURBO ACTIVATED!
Ferrari accelerating to 320 km/hHoja de referencia
La palabra clave on restringe un mixin para que solo se use con clases que extienden un tipo específico. Esto permite que el mixin acceda de forma segura a los métodos y propiedades de la clase base.
class Animal {
String name;
Animal(this.name);
void breathe() => print('$name is breathing');
}
mixin Swimming on Animal {
void swim() {
print('$name is swimming'); // Can access 'name' from Animal
breathe(); // Can call Animal's methods
}
}
class Fish extends Animal with Swimming {
Fish(String name) : super(name);
}La declaración on Animal garantiza que el mixin tenga acceso a los miembros de Animal. Sin ella, el mixin no sabría que name o breathe() existen.
Intentar usar un mixin restringido en una clase incompatible resulta en un error de tiempo de compilación:
class Robot with Swimming {} // Error! Robot doesn't extend AnimalEsta restricción es útil cuando la funcionalidad de su mixin depende de capacidades específicas de una clase base, creando un contrato más seguro entre el mixin y las clases que lo utilizan.
Pruébalo tú mismo
import 'vehicles.dart';
void main() {
// TODO: Crear un SportsCar con el modelo 'Ferrari', velocidad 320 y color 'Red'
// TODO: Llamar a showOff()
// TODO: Llamar a activateTurbo()
}
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 Repository