Introducción a los Mixins
Parte de la sección Programación Orientada a Objetos del Journey de Dart de Coddy. Lección 50 de 110.
Has aprendido que Dart solo permite extender una clase y, aunque puedes implementar múltiples interfaces, debes escribir todo el código tú mismo. ¿Pero qué pasa si quieres compartir código de implementación real entre múltiples clases no relacionadas? Aquí es donde entran los mixins.
Un mixin es una forma de reutilizar código en varias jerarquías de clases. Piensa en él como un conjunto de métodos y propiedades que puedes «mezclar» en cualquier clase, proporcionándole nuevas capacidades sin usar la herencia.
mixin Swimming {
void swim() {
print('Swimming through the water');
}
}
class Duck with Swimming {
void quack() {
print('Quack!');
}
}
class Fish with Swimming {
void blowBubbles() {
print('Blub blub');
}
}
void main() {
var duck = Duck();
duck.quack();
duck.swim(); // Desde el mixin
var fish = Fish();
fish.swim(); // Misma implementación, diferente clase
}Observa la palabra clave with: así es como aplicas un mixin a una clase. A diferencia de implements, no necesitas escribir el método tú mismo. El mixin proporciona el código real, y tu clase obtiene esa funcionalidad automáticamente.
Los mixins resuelven un problema real: Duck y Fish no están relacionados mediante herencia, pero ambos necesitan el comportamiento de nadar. Con los mixins, escribes el código una vez y lo compartes donde sea necesario.
Desafío
FácilConstruyamos un sistema de instrumentos musicales que demuestre cómo los mixins permiten compartir comportamiento entre clases no relacionadas. Crearás un mixin que proporciona funcionalidad de afinación y, después, lo aplicarás a distintos instrumentos que no están relacionados mediante herencia.
Organizarás tu código en dos archivos:
instruments.dart: Define aquí tu mixin y las clases de instrumentos:- Un mixin
Tunablecon un métodotune()que imprimeTuning the instrument...y un métodocheckTuning()que imprimeTuning is perfect! - Una clase
Guitarque usa el mixinTunable. Añade una propiedadString brandcon un constructor. Incluye un métodostrum()que imprime[brand] guitar strumming chords - Una clase
Pianoque también usa el mixinTunable. Añade una propiedadint keyscon un constructor. Incluye un métodoplay()que imprimePlaying [keys]-key piano
- Un mixin
main.dart: Importa tu archivo de instrumentos y demuestra cómo ambos instrumentos no relacionados obtienen capacidades de afinación del mismo mixin:- Crea una
Guitarcon la marca'Fender' - Crea un
Pianocon88teclas - Para la guitarra: llama a
tune(), después astrum()y después acheckTuning() - Imprime una línea vacía
- Para el piano: llama a
tune(), después aplay()y después acheckTuning()
- Crea una
Observa cómo Guitar y Piano son instrumentos completamente diferentes sin ninguna relación de herencia y, aun así, ambos obtienen exactamente los mismos métodos de afinación del mixin Tunable. Escribes el código de afinación una sola vez y ambas clases pueden usarlo con la palabra clave with.
Salida esperada:
Tuning the instrument...
Fender guitar strumming chords
Tuning is perfect!
Tuning the instrument...
Playing 88-key piano
Tuning is perfect!Pruébalo tú mismo
import 'instruments.dart';
void main() {
// TODO: Crear una Guitarra con la marca 'Fender'
// TODO: Crear un Piano con 88 teclas
// TODO: Para la guitarra: llamar a tune(), luego strum(), luego checkTuning()
// TODO: Imprimir una línea vacía
// TODO: Para el piano: llamar a tune(), luego play(), luego checkTuning()
}
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