Menu
CoddyTech

Composition ou héritage

Fait partie de la section Programmation Orientée Objet du Journey Dart de Coddy. Leçon 82 sur 110.

Vous avez appris que l’héritage crée une relation « est-un » : un Dog est un Animal. Mais il existe une autre approche puissante : la composition, qui crée une relation « a-un ». Au lieu d’hériter d’un comportement, une classe contient des instances d’autres classes et leur délègue le travail.

Considère une classe Car. Avec l’héritage, tu pourrais essayer d’étendre une classe Engine — mais une voiture n’est pas un moteur, elle a un moteur :

class Engine {
  void start() => print('Engine started');
}

class Car {
  final Engine _engine = Engine();  // Composition : Car POSSÈDE un Engine
  
  void start() {
    _engine.start();  // Déléguer au moteur
    print('Car is ready to drive');
  }
}

void main() {
  var car = Car();
  car.start();
}

Le principal avantage de la composition est sa flexibilité. Avec l’héritage, tu es limité à une seule classe parente. Avec la composition, tu peux combiner plusieurs composants et même les remplacer à l’exécution :

class ElectricEngine {
  void start() => print('Electric motor humming');
}

class HybridCar {
  Engine? _gasEngine;
  ElectricEngine? _electricEngine;
  
  HybridCar({bool useElectric = false}) {
    if (useElectric) {
      _electricEngine = ElectricEngine();
    } else {
      _gasEngine = Engine();
    }
  }
}

Une recommandation courante est de « privilégier la composition plutôt que l’héritage ». Utilisez l’héritage lorsqu’il existe une véritable relation « est-un » et que vous avez besoin de polymorphisme. Utilisez la composition lorsque vous souhaitez réutiliser un comportement sans couplage étroit, ou lorsqu’un objet a besoin de capacités provenant de plusieurs sources.

challenge icon

Défi

Facile

Construisons un système informatique à l’aide de la composition ! Au lieu d’essayer de faire hériter un ordinateur de ses composants, tu vas créer des classes distinctes pour les composants et les assembler, car un ordinateur possède un CPU et de la mémoire : ce n’est ni un CPU ni de la mémoire.

Tu vas organiser ton code dans trois fichiers :

  • components.dart : crée deux classes de composants représentant les pièces d’un ordinateur :
    • Une classe CPU avec un String brand et un double speedGHz. Inclue une méthode process() qui renvoie une chaîne de caractères : [brand] processing at [speedGHz]GHz
    • Une classe Memory avec un int sizeGB. Inclue une méthode load() qui renvoie une chaîne de caractères : Loading [sizeGB]GB of data
  • computer.dart : crée une classe Computer qui utilise la composition pour combiner les composants. Ton ordinateur doit :
    • Avoir un champ String name
    • Contenir une instance de CPU et une instance de Memory (composition : l’ordinateur POSSÈDE ces composants)
    • Accepter toutes les valeurs nécessaires dans son constructeur afin de créer les deux composants en interne
    • Avoir une méthode boot() qui délègue le travail aux deux composants et affiche trois lignes : le nom de l’ordinateur suivi de starting..., puis le résultat de la méthode process du CPU, puis le résultat de la méthode load de Memory
    • Avoir une méthode specs() qui renvoie une chaîne décrivant le système : [name]: [brand] [speedGHz]GHz, [sizeGB]GB RAM
  • main.dart : importe tes fichiers et montre la composition en action :
    • Crée un Computer nommé Workstation, avec un CPU Intel fonctionnant à 3.5 GHz et 16 Go de mémoire
    • Appelle la méthode boot()
    • Affiche le résultat de specs()

Remarque que la classe Computer n’étend ni CPU ni Memory : elle les contient et leur délègue le travail. C’est la relation « possède-un » que crée la composition !

Résultat attendu :

Workstation starting...
Intel processing at 3.5GHz
Loading 16GB of data
Workstation: Intel 3.5GHz, 16GB RAM

Essayez vous-même

import 'computer.dart';

void main() {
  // TODO: Créer un Computer nommé "Workstation" avec :
  // - un processeur Intel fonctionnant à 3.5 GHz
  // - 16 GB de mémoire

  // TODO: Appeler la méthode boot()

  // TODO: Afficher le résultat de specs()
}
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

Entraînez-vous par vous-même : Compilateur Dart en ligne