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.
Défi
FacileConstruisons un système d'instruments de musique qui démontre le polymorphisme en action. Tu vas 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.
Tu organiseras ton code en deux fichiers :
instruments.dart: Définis ici ta hiérarchie d'instruments :- Une classe
Instrumentavec une propriétéString nameet un constructeur. Inclus une méthodeplay()qui affiche[name] makes a sound - Une classe
Guitarqui étendInstrumentet redéfinitplay()pour afficher[name] strums melodically - Une classe
Drumqui étendInstrumentet redéfinitplay()pour afficher[name] beats rhythmically - Une classe
Pianoqui étendInstrumentet redéfinitplay()pour afficher[name] plays harmoniously
performConcert(List<Instrument> instruments)qui afficheConcert begins!, parcourt ensuite la liste en appelantplay()sur chaque instrument, puis affiche finalementConcert ends!- Une classe
main.dart: Importe ton fichier d'instruments et démontre le polymorphisme en créant un groupe mixte :- Crée une liste de type
List<Instrument>contenant uneGuitarnommée'Acoustic', unDrumnommé'Snare'et unPianonommé'Grand' - Transmets cette liste à
performConcert()
- Crée une liste de type
Remarque que performConcert() fonctionne avec le type parent Instrument, tandis que chaque instrument joue d'une manière qui lui est propre. Il s'agit du polymorphisme : le même appel de méthode produit un comportement différent selon le type réel de l'objet.
Résultat attendu :
Concert begins!
Acoustic strums melodically
Snare beats rhythmically
Grand plays harmoniously
Concert ends!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
}
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
1Fondamentaux de la POO
Fichiers externesBibliothèques et importsIntroduction à la POOClasses vs objetsLe mot-clé thisMéthodesVariables d’instanceBases des constructeursRécapitulatif - Calculatrice simple4Sécurité face aux valeurs nulles
Introduction à la sécurité face aux valeurs nullesNullable vs Non-NullableLes opérateurs ? et !Mot-clé Late et sécurité face aux valeurs nullesOpérateurs sensibles à nullSécurité face aux valeurs nulles dans les classesRécapitulatif – Système de profil utilisateur7Classes abstraites et interfaces
Classes abstraitesMéthodes abstraitesInterfaces en DartInterfaces implicitesImplémenter ou étendreInterfaces multiplesRécapitulatif - Calculateur de formes10Collections et génériques
Vue d’ensemble des List, Set et MapCollections à typage sûrClasses génériquesMéthodes génériquesContraintes génériquesIterable et IteratorRécapitulatif – stockage générique2Constructeurs en Dart
Constructeur par défautConstructeurs nommésListes d'initialisationConstructeurs constantsConstructeurs factoryConstructeurs redirigésRécapitulatif - Constructeur de formes5Encapsulation
Membres publics vs privésLa convention du préfixe _Confidentialité au niveau de la bibliothèqueApprofondissement des getters et settersMasquage de l’informationRécapitulatif - Fiches des étudiants8Mixins
Introduction aux MixinsCréer des MixinsUtiliser plusieurs MixinsMot-clé on dans les MixinsMixin ou héritageMixin ou interfaceRécapitulatif - Système animal11Méthodes spéciales
Redéfinition de toString()Redéfinition de hashCode et ==Interface ComparableMéthode call()Redéfinition de noSuchMethodRécapitulatif - Collection personnalisée14Patrons de conception, partie 1
Introduction aux patrons de conceptionPatron SingletonPatron FactoryPatron ObserverPatron Strategy3Propriétés des classes
Membres d’instance et statiquesChamps Final et ConstVariables différéesMéthodes et champs statiquesAccesseurs et mutateursRécapitulatif - Gestionnaire de compte bancaire6Héritage
Héritage de baseLe mot-clé superRedéfinition de méthodeL’annotation @overrideLe mot-clé de classe finalConstructeurs et héritageRécapitulatif – Hiérarchie des employés9Polymorphisme
Bases du polymorphismePolymorphisme via les interfacesVérification des types à l’exécutionLes opérateurs is et asMot-clé covariantRécapitulatif - Processeur de paiements12POO asynchrone
Futures et async/awaitNotions de base des StreamsContrôleurs de StreamsConstructeurs asynchronesAsynchrone dans les méthodes de classeRécapitulatif - récupérateur de données15Patrons de conception – Partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Méthode modèlePatron ÉtatPatron CompositePatron DépôtEntraînez-vous par vous-même : Compilateur Dart en ligne