Implémenter ou étendre
Fait partie de la section Programmation Orientée Objet du Journey Dart de Coddy. Leçon 47 sur 110.
Maintenant que tu comprends à la fois extends et implements, clarifions quand utiliser chacun d’eux.
Utilisez extends lorsque vous souhaitez hériter d’un comportement. Votre sous-classe obtient gratuitement tout le code de la classe parente et peut s’appuyer dessus :
class Animal {
void breathe() {
print('Breathing...');
}
}
class Dog extends Animal {
void bark() {
print('Woof!');
}
}
void main() {
var dog = Dog();
dog.breathe(); // Hérité - fonctionne automatiquement
dog.bark();
}Utilisez implements lorsque vous voulez garantir une structure sans hériter de code. Vous devez écrire chaque méthode vous-même :
class Robot implements Animal {
@override
void breathe() {
print('Ventilating circuits...'); // Implémentation complètement personnalisée
}
}La différence essentielle : extends signifie « Je suis un type de ceci », tandis que implements signifie « Je peux faire ce que ceci fait ». Un Dog est un Animal et respire de la même manière. Un Robot n’est pas un animal, mais il peut respecter le même contrat avec sa propre logique.
Rappelle-toi : tu ne peux étendre qu’une seule classe, mais tu peux implémenter de nombreuses interfaces. Choisis extends pour les véritables relations d’héritage, et implements lorsque tu as besoin de flexibilité ou que tu veux imposer un contrat sans partager les détails de l’implémentation.
Défi
FacileConstruisons un système de travailleurs qui démontre quand utiliser extends plutôt que implements. Vous allez créer une classe de base pour les travailleurs, puis présenter les deux approches : une classe qui « est un » travailleur et hérite de son comportement, et une autre qui peut simplement « faire » ce que fait un travailleur, mais avec une logique entièrement personnalisée.
Vous organiserez votre code en deux fichiers :
worker.dart: définissez ici votre hiérarchie de travailleurs :- Une classe
Workeravec une propriétéString nameet un constructeur. Incluez une méthodework()qui affiche[name] is working...et une méthodetakeBreak()qui affiche[name] takes a coffee break - Une classe
OfficeWorkerqui étendWorker. Ajoutez une propriétéString department. Surchargezwork()pour afficher[name] is typing reports in [department], tout en conservant le comportement hérité detakeBreak() - Une classe
RobotWorkerqui implémenteWorker. Ajoutez une propriétéString model. Comme les robots ne sont pas réellement des travailleurs, mais peuvent faire ce que font les travailleurs, fournissez des implémentations entièrement personnalisées :work()doit afficherRobot [model] is assembling partsettakeBreak()doit afficherRobot [model] is recharging
- Une classe
main.dart: importez votre fichier de travailleurs et présentez les deux approches :- Créez un
OfficeWorkernommé'Alice'dans le service'Marketing' - Créez un
RobotWorkeravec le modèle'RX-7' - Pour le travailleur de bureau, appelez
work()puistakeBreak() - Affichez une ligne vide
- Pour le robot, appelez
work()puistakeBreak()
- Créez un
Remarquez comment OfficeWorker hérite automatiquement de takeBreak() parce qu’il étend Worker — c’est véritablement « un » travailleur. En revanche, RobotWorker doit fournir sa propre implémentation pour chaque élément, car il ne fait qu’implémenter l’interface — il peut « faire » ce que fait un travailleur, mais à sa propre manière robotique.
Sortie attendue :
Alice is typing reports in Marketing
Alice takes a coffee break
Robot RX-7 is assembling parts
Robot RX-7 is rechargingEssayez vous-même
import 'worker.dart';
void main() {
// TODO: Créer un OfficeWorker nommé 'Alice' dans le département 'Marketing'
// TODO: Créer un RobotWorker avec le modèle 'RX-7'
// TODO: Pour le travailleur de bureau, appeler work() puis takeBreak()
// TODO: Afficher une ligne vide
// TODO: Pour le travailleur robot, appeler work() puis takeBreak()
}
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