Menu
Coddy logo textTech

Bases du polymorphisme

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

Le polymorphisme signifie « plusieurs formes » : c'est la capacité de traiter des objets de différentes classes via une interface commune. Lorsque vous avez une référence de classe parente, elle peut pointer vers n'importe quel objet de classe enfant, et la méthode appropriée est appelée en fonction du type d'objet réel.

C'est puissant car vous pouvez écrire du code qui fonctionne avec le type parent, tout en gérant automatiquement tous les types enfants correctement :

class Animal {
  void speak() => print('Some sound');
}

class Dog extends Animal {
  @override
  void speak() => print('Woof!');
}

class Cat extends Animal {
  @override
  void speak() => print('Meow!');
}

void main() {
  Animal myPet = Dog();  // Type parent, objet enfant
  myPet.speak();  // Sortie : Woof!
  
  myPet = Cat();  // Même variable, objet différent
  myPet.speak();  // Sortie : Meow!
}

La variable myPet est déclarée comme Animal, mais elle contient un Dog ou un Cat. Lorsque speak() est appelée, Dart examine le type réel de l'objet au moment de l'exécution et appelle la méthode redéfinie appropriée.

Cela vous permet d'écrire des fonctions flexibles qui fonctionnent avec n'importe quelle sous-classe :

void makeAllSpeak(List<Animal> animals) {
  for (var animal in animals) {
    animal.speak();  // Chaque animal s'exprime à sa manière
  }
}

void main() {
  var pets = [Dog(), Cat(), Dog()];
  makeAllSpeak(pets);
  // Sortie : Woof! Meow! Woof!
}

La fonction n'a pas besoin de connaître Dog ou Cat - elle fonctionne simplement avec Animal. Cela rend votre code plus extensible car l'ajout de nouveaux types d'animaux ne nécessite aucune modification des fonctions existantes.

challenge icon

Défi

Facile

Construisons un système d'instruments de musique qui démontre le polymorphisme en action. Vous allez créer une classe de base Instrument et plusieurs types d'instruments, puis écrire une fonction capable de faire jouer ensemble n'importe quelle collection d'instruments - sans connaître leurs types spécifiques.

Vous organiserez votre code en deux fichiers :

  • instruments.dart : Définissez votre hiérarchie d'instruments ici :
    • Une classe Instrument avec une propriété String name et un constructeur. Incluez une méthode play() qui affiche '$name makes a sound'
    • Une classe Guitar qui étend Instrument et surcharge play() pour afficher '$name strums melodically'
    • Une classe Drum qui étend Instrument et surcharge play() pour afficher '$name beats rhythmically'
    • Une classe Piano qui étend Instrument et surcharge play() pour afficher '$name plays harmoniously'
    Créez également une fonction performConcert(List<Instrument> instruments) qui affiche 'Concert begins!', puis parcourt la liste en appelant play() sur chaque instrument, et affiche enfin 'Concert ends!'
  • main.dart : Importez votre fichier d'instruments et démontrez le polymorphisme en créant un groupe mixte :
    • Créez une liste de type List<Instrument> contenant une Guitar nommée 'Acoustic', un Drum nommé 'Snare', et un Piano nommé 'Grand'
    • Passez cette liste à performConcert()

Remarquez comment performConcert() fonctionne avec le type parent Instrument, pourtant chaque instrument joue de sa propre manière unique. C'est le polymorphisme - le même appel de méthode produit un comportement différent selon le type réel de l'objet.

Sortie attendue :

Concert begins!
Acoustic strums melodically
Snare beats rhythmically
Grand plays harmoniously
Concert ends!

Aide-mémoire

Le polymorphisme signifie "plusieurs formes" - il vous permet de traiter des objets de différentes classes via une interface commune. Une référence de classe parente peut pointer vers n'importe quel objet de classe enfant, et la méthode correcte est appelée en fonction du type d'objet réel au moment de l'exécution.

Exemple de polymorphisme de base :

class Animal {
  void speak() => print('Some sound');
}

class Dog extends Animal {
  @override
  void speak() => print('Woof!');
}

class Cat extends Animal {
  @override
  void speak() => print('Meow!');
}

void main() {
  Animal myPet = Dog();  // Type parent, objet enfant
  myPet.speak();  // Output: Woof!
  
  myPet = Cat();  // Même variable, objet différent
  myPet.speak();  // Output: Meow!
}

Le polymorphisme permet de créer des fonctions flexibles qui fonctionnent avec n'importe quelle sous-classe :

void makeAllSpeak(List<Animal> animals) {
  for (var animal in animals) {
    animal.speak();  // Chaque animal s'exprime à sa manière
  }
}

void main() {
  var pets = [Dog(), Cat(), Dog()];
  makeAllSpeak(pets);
  // Output: Woof! Meow! Woof!
}

La fonction travaille avec le type parent Animal sans avoir besoin de connaître les classes enfants spécifiques comme Dog ou Cat. Cela rend le code plus extensible - l'ajout de nouveaux types ne nécessite aucune modification des fonctions existantes.

Essayez vous-même

import 'instruments.dart';

void main() {
  // TODO: Créer une List<Instrument> contenant :
  // - Une Guitar nommée 'Acoustic'
  // - Un Drum nommé 'Snare'
  // - Un Piano nommé 'Grand'
  
  
  // TODO: Appeler performConcert() avec votre liste d'instruments
  
}
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