Menu
Coddy logo textTech

Introduction aux Mixins

Fait partie de la section Programmation Orientée Objet du Journey Dart de Coddy — leçon 50 sur 110.

Vous avez appris que Dart ne permet d'étendre qu'une seule classe, et bien que vous puissiez implémenter plusieurs interfaces, vous devez écrire tout le code vous-même. Mais que se passe-t-il si vous voulez partager du code d'implémentation réel entre plusieurs classes non liées ? C'est là que les mixins entrent en jeu.

Un mixin est un moyen de réutiliser du code dans plusieurs hiérarchies de classes. Considérez-le comme un ensemble de méthodes et de propriétés que vous pouvez « mélanger » à n'importe quelle classe, lui conférant de nouvelles capacités sans utiliser l'héritage.

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();  // Provient du mixin
  
  var fish = Fish();
  fish.swim();  // Même implémentation, classe différente
}

Remarquez le mot-clé with - c'est ainsi que vous appliquez un mixin à une classe. Contrairement à implements, vous n'avez pas besoin d'écrire la méthode vous-même. Le mixin fournit le code réel, et votre classe acquiert cette fonctionnalité automatiquement.

Les mixins résolvent un problème réel : Duck et Fish ne sont pas liés par l'héritage, pourtant ils ont tous deux besoin d'un comportement de nage. Avec les mixins, vous écrivez le code une seule fois et vous le partagez partout où c'est nécessaire.

challenge icon

Défi

Facile

Construisons un système d'instruments de musique qui démontre comment les mixins vous permettent de partager un comportement entre des classes non liées. Vous allez créer un mixin qui fournit une fonctionnalité d'accordage, puis l'appliquer à différents instruments qui ne sont pas liés par héritage.

Vous organiserez votre code en deux fichiers :

  • instruments.dart : Définissez votre mixin et vos classes d'instruments ici :
    • Un mixin Tunable avec une méthode tune() qui affiche Tuning the instrument... et une méthode checkTuning() qui affiche Tuning is perfect!
    • Une classe Guitar qui utilise le mixin Tunable. Ajoutez une propriété String brand avec un constructeur. Incluez une méthode strum() qui affiche [brand] guitar strumming chords
    • Une classe Piano qui utilise également le mixin Tunable. Ajoutez une propriété int keys avec un constructeur. Incluez une méthode play() qui affiche Playing [keys]-key piano
  • main.dart : Importez votre fichier d'instruments et démontrez comment les deux instruments non liés acquièrent des capacités d'accordage à partir du même mixin :
    • Créez une Guitar avec la marque 'Fender'
    • Créez un Piano avec 88 touches
    • Pour la guitare : appelez tune(), puis strum(), puis checkTuning()
    • Affichez une ligne vide
    • Pour le piano : appelez tune(), puis play(), puis checkTuning()

Remarquez comment Guitar et Piano sont des instruments complètement différents sans relation d'héritage, et pourtant ils bénéficient tous deux des mêmes méthodes d'accordage grâce au mixin Tunable. Vous écrivez le code d'accordage une seule fois, et les deux classes peuvent l'utiliser avec le mot-clé with.

Sortie attendue :

Tuning the instrument...
Fender guitar strumming chords
Tuning is perfect!

Tuning the instrument...
Playing 88-key piano
Tuning is perfect!

Aide-mémoire

Un mixin est un moyen de réutiliser du code à travers plusieurs classes non liées sans utiliser l'héritage. C'est un ensemble de méthodes et de propriétés que vous pouvez « mélanger » à n'importe quelle classe.

Définissez un mixin en utilisant le mot-clé mixin :

mixin Swimming {
  void swim() {
    print('Swimming through the water');
  }
}

Appliquez un mixin à une classe en utilisant le mot-clé with :

class Duck with Swimming {
  void quack() {
    print('Quack!');
  }
}

class Fish with Swimming {
  void blowBubbles() {
    print('Blub blub');
  }
}

Contrairement à implements, vous n'avez pas besoin d'écrire l'implémentation de la méthode vous-même - le mixin fournit le code réel, et votre classe acquiert cette fonctionnalité automatiquement.

Duck et Fish peuvent désormais tous deux utiliser la méthode swim() même s'ils ne sont pas liés par l'héritage :

var duck = Duck();
duck.swim();  // Provient du mixin

var fish = Fish();
fish.swim();  // Même implémentation, classe différente

Essayez vous-même

import 'instruments.dart';

void main() {
  // TODO: Créer une Guitar avec la marque 'Fender'
  
  // TODO: Créer un Piano avec 88 touches
  
  // TODO: Pour la guitare : appeler tune(), puis strum(), puis checkTuning()
  
  // TODO: Imprimer une ligne vide
  
  // TODO: Pour le piano : appeler tune(), puis play(), puis checkTuning()
}
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Programmation Orientée Objet