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

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