Menu
Coddy logo textTech

Composition vs 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érez une classe Car. Avec l'héritage, vous pourriez 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 A un Engine
  
  void start() {
    _engine.start();  // Déléguer au moteur
    print('Car is ready to drive');
  }
}

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

L'avantage clé de la composition est la flexibilité. Avec l'héritage, vous êtes lié à une seule classe parente. Avec la composition, vous pouvez combiner plusieurs composants et même les échanger au moment de 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 directive courante est « favoriser la composition plutôt que l'héritage ». Utilisez l'héritage lorsqu'il existe une véritable relation « est un » (is-a) 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 en utilisant la composition ! Au lieu d'essayer de faire hériter un ordinateur de ses composants, vous allez créer des classes de composants distinctes et les composer ensemble - parce qu'un ordinateur a un processeur et a de la mémoire, il n'est pas un processeur ou une mémoire.

Vous organiserez votre code en trois fichiers :

  • components.dart : Créez deux classes de composants qui représentent les pièces de l'ordinateur :
    • Une classe CPU avec un String brand et un double speedGHz. Incluez une méthode process() qui retourne une chaîne : [brand] processing at [speedGHz]GHz
    • Une classe Memory avec un int sizeGB. Incluez une méthode load() qui retourne une chaîne : Loading [sizeGB]GB of data
  • computer.dart : Créez une classe Computer qui utilise la composition pour combiner les composants. Votre ordinateur doit :
    • Avoir un champ String name
    • Contenir une instance de CPU et une instance de Memory (composition - l'ordinateur A ces pièces)
    • Accepter toutes les valeurs nécessaires via son constructeur pour créer les deux composants en interne
    • Avoir une méthode boot() qui délègue 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 la Memory
    • Avoir une méthode specs() qui retourne une chaîne décrivant le système : [name]: [brand] [speedGHz]GHz, [sizeGB]GB RAM
  • main.dart : Importez vos fichiers et démontrez la composition en action :
    • Créez un Computer nommé Workstation avec un CPU Intel cadencé à 3.5 GHz et 16 Go de mémoire
    • Appelez la méthode boot()
    • Affichez le résultat de specs()

Remarquez comment la classe Computer n'étend pas CPU ou Memory - elle les contient et leur délègue le travail. C'est la relation "a-un" (has-a) que la composition crée !

Sortie attendue :

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 :
  // - CPU Intel cadencé à 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