Introduzione ai Mixin
Fa parte della sezione Programmazione orientata agli oggetti del percorso Dart di Coddy. Lezione 50 di 110.
Hai imparato che Dart consente di estendere una sola classe e che, anche se puoi implementare più interfacce, devi scrivere tutto il codice da solo. Ma cosa succede se vuoi condividere codice di implementazione effettivo tra più classi non correlate? È qui che entrano in gioco i mixin.
Un mixin è un modo per riutilizzare il codice in più gerarchie di classi. Pensalo come un insieme di metodi e proprietà che puoi «mescolare» in qualsiasi classe, assegnandole nuove capacità senza usare l’ereditarietà.
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(); // Del mixin
var fish = Fish();
fish.swim(); // Misma implementación, clase diferente
}Nota la parola chiave with: è così che applichi un mixin a una classe. A differenza di implements, non devi scrivere il metodo tu stesso. Il mixin fornisce il codice vero e proprio e la tua classe acquisisce automaticamente questa funzionalità.
I mixin risolvono un problema concreto: Duck e Fish non sono correlati tramite ereditarietà, eppure entrambi hanno bisogno del comportamento di nuoto. Con i mixin, scrivi il codice una sola volta e lo condividi ovunque sia necessario.
Sfida
FacileCostruiamo un sistema di strumenti musicali che mostri come i mixin permettano di condividere comportamenti tra classi non correlate. Creerai un mixin che fornisce funzionalità di accordatura, poi lo applicherai a diversi strumenti che non sono correlati tramite ereditarietà.
Organizzerai il codice in due file:
instruments.dart: definisci qui il tuo mixin e le classi degli strumenti:- Un mixin
Tunablecon un metodotune()che stampaTuning the instrument...e un metodocheckTuning()che stampaTuning is perfect! - Una classe
Guitarche usa il mixinTunable. Aggiungi una proprietàString brandcon un costruttore. Includi un metodostrum()che stampa[brand] guitar strumming chords - Una classe
Pianoche usa anch'essa il mixinTunable. Aggiungi una proprietàint keyscon un costruttore. Includi un metodoplay()che stampaPlaying [keys]-key piano
- Un mixin
main.dart: importa il file degli strumenti e mostra come entrambi gli strumenti non correlati acquisiscano funzionalità di accordatura dallo stesso mixin:- Crea una
Guitarcon il marchio'Fender' - Crea un
Pianocon88tasti - Per la chitarra: chiama
tune(), poistrum(), poicheckTuning() - Stampa una riga vuota
- Per il pianoforte: chiama
tune(), poiplay(), poicheckTuning()
- Crea una
Nota come Guitar e Piano siano strumenti completamente diversi e non abbiano alcuna relazione di ereditarietà, eppure entrambi acquisiscano esattamente gli stessi metodi di accordatura dal mixin Tunable. Scrivi il codice per l'accordatura una sola volta ed entrambe le classi possono usarlo con la parola chiave with.
Output previsto:
Tuning the instrument...
Fender guitar strumming chords
Tuning is perfect!
Tuning the instrument...
Playing 88-key piano
Tuning is perfect!Provalo tu
import 'instruments.dart';
void main() {
// TODO: Crea una Guitar di marca 'Fender'
// TODO: Crea un Piano con 88 tasti
// TODO: Per la chitarra: chiama tune(), poi strum(), poi checkTuning()
// TODO: Stampa una riga vuota
// TODO: Per il pianoforte: chiama tune(), poi play(), poi checkTuning()
}
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Programmazione orientata agli oggetti
1Fondamenti della programmazione orientata agli oggetti
File esterniLibrerie e importazioniIntroduzione alla programmazione orientata agli oggettiClassi e oggettiLa parola chiave thisMetodiVariabili di istanzaFondamenti dei costruttoriRiepilogo - Calcolatrice semplice4Sicurezza dei valori null
Introduzione alla sicurezza dei valori nullNullable e non nullableGli operatori ? e !La keyword late e la sicurezza dei valori nullOperatori null-awareSicurezza dei valori null nelle classiRiepilogo - Sistema di profili utente7Classi astratte e interfacce
Classi astratteMetodi astrattiInterfacce in DartInterfacce impliciteImplementare vs estendereInterfacce multipleRiepilogo - Calcolatore di forme10Collezioni e generici
Panoramica di List, Set e MapCollezioni sicure rispetto ai tipiClassi genericheMetodi genericiVincoli sui genericiIterable e IteratorRiepilogo - Archiviazione generica13Concetti avanzati di OOP
Composizione vs ereditarietàMetodi di estensioneClassi chiamabiliClassi sealed (Dart 3)Record (Dart 3)Pattern e matching (3.0)Enum con metodi16Progetto: Gestione della biblioteca
Panoramica del progettoClassi Libro e Utente2I costruttori in Dart
Costruttore predefinitoCostruttori con nomeListe di inizializzazioneCostruttori costantiCostruttori factoryCostruttori di reindirizzamentoRiepilogo - Crea forme5Incapsulamento
Membri pubblici e privatiConvenzione del prefisso _Visibilità a livello di libreriaApprofondimento su getter e setterNascondimento delle informazioniRiepilogo - Registri degli studenti8Mixin
Introduzione ai MixinCreare MixinUsare più MixinParola chiave on nei MixinMixin vs ereditarietàMixin vs interfacciaRiepilogo - Sistema animale11Metodi speciali
Sovrascrittura di toString()Sovrascrittura di hashCode e ==Interfaccia ComparableMetodo call()Sovrascrittura di noSuchMethodRiepilogo - Collezione personalizzata14Modelli di progettazione Parte 1
Introduzione ai modelli di progettazioneSingletonFactoryObserverStrategy3Proprietà delle classi
Membri di istanza e staticiCampi final e constVariabili lateMetodi e campi staticiGetter e setterRiepilogo - Gestore di conti bancari6Ereditarietà
Ereditarietà di baseLa parola chiave superOverride dei metodiL’annotazione @overrideLa parola chiave final per le classiCostruttori ed ereditarietàRiepilogo - Gerarchia dei dipendenti9Polimorfismo
Fondamenti di polimorfismoPolimorfismo tramite interfacceControllo del tipo a runtimeGli operatori is e asParola chiave covariantRiepilogo - Elaboratore di pagamenti12OOP asincrona
Future e async/awaitNozioni di base sugli streamController degli streamCostruttori asincroniAsync nei metodi di classeRiepilogo - Recupero dei dati15Pattern di progettazione Parte 2
Pattern CommandPattern AdapterPattern DecoratorPattern Template MethodPattern StatePattern CompositePattern RepositoryEsercitati da solo: Compilatore Dart online