Classes abstraites
Fait partie de la section Programmation Orientée Objet du Journey Dart de Coddy — leçon 43 sur 110.
Une classe abstraite est une classe qui ne peut pas être instanciée directement. Elle sert de modèle pour d'autres classes, définissant une structure commune que les sous-classes doivent suivre. Vous en créez une en utilisant le mot-clé abstract.
abstract class Shape {
String color;
Shape(this.color);
void describe() {
print('A $color shape');
}
}
class Circle extends Shape {
double radius;
Circle(String color, this.radius) : super(color);
}
void main() {
// Shape s = Shape('red'); // Erreur ! Impossible d'instancier une classe abstraite
var circle = Circle('blue', 5.0);
circle.describe(); // Une forme bleue
}Les classes abstraites sont utiles lorsque vous avez un concept trop général pour exister par lui-même. Une « Forme » est une idée, mais vous ne pouvez pas dessiner une forme sans savoir s'il s'agit d'un cercle, d'un rectangle ou d'un triangle. La classe abstraite définit ce que toutes les formes ont en commun, tandis que les sous-classes concrètes fournissent les détails spécifiques.
Notez que les classes abstraites peuvent toujours avoir des méthodes régulières avec des implémentations (comme describe()) et des constructeurs. Les sous-classes en héritent tout comme avec l'héritage normal. La différence clé est simplement que vous ne pouvez pas créer d'instance de la classe abstraite elle-même - vous devez utiliser une sous-classe concrète.
Défi
FacileConstruisons un système de véhicules qui démontre comment les classes abstraites servent de modèles pour des types plus spécifiques. Vous allez créer une classe de base abstraite qui définit ce que tous les véhicules ont en commun, puis l'étendre avec des types de véhicules concrets.
Vous organiserez votre code en deux fichiers :
vehicle.dart: Définissez votre hiérarchie de véhicules ici :- Une
abstract class Vehicleavec une propriétéString brandetint year. Incluez un constructeur qui prend les deux valeurs et une méthodedisplayInfo()qui affiche[brand] ([year]) - Une classe
Carqui étendVehicleet ajoute une propriétéint doors. Incluez une méthodehonk()qui afficheBeep beep! - Une classe
Motorcyclequi étendVehicleet ajoute une propriétébool hasSidecar. Incluez une méthoderevEngine()qui afficheVroom!
- Une
main.dart: Importez votre fichier de véhicule et démontrez le fonctionnement des classes abstraites :- Créez une
Caravec la marque'Toyota', l'année2022, et le nombre de portes4 - Appelez sa méthode
displayInfo()(héritée de Vehicle) - Affichez
Doors: [doors] - Appelez sa méthode
honk() - Affichez une ligne vide
- Créez une
Motorcycleavec la marque'Harley', l'année2021, et hasSidecarfalse - Appelez sa méthode
displayInfo() - Affichez
Has sidecar: [hasSidecar] - Appelez sa méthode
revEngine()
- Créez une
Rappelez-vous que vous ne pouvez pas créer une instance de Vehicle directement puisqu'elle est abstraite - vous devez utiliser l'une des sous-classes concrètes. Car et Motorcycle héritent toutes deux de la méthode displayInfo() de la classe parente abstraite.
Sortie attendue :
Toyota (2022)
Doors: 4
Beep beep!
Harley (2021)
Has sidecar: false
Vroom!Aide-mémoire
Une classe abstraite est une classe qui ne peut pas être instanciée directement. Elle sert de modèle pour d'autres classes, définissant une structure commune que les sous-classes doivent suivre. Créez-en une en utilisant le mot-clé abstract :
abstract class Shape {
String color;
Shape(this.color);
void describe() {
print('A $color shape');
}
}
class Circle extends Shape {
double radius;
Circle(String color, this.radius) : super(color);
}
void main() {
// Shape s = Shape('red'); // Erreur ! Impossible d'instancier une classe abstraite
var circle = Circle('blue', 5.0);
circle.describe(); // A blue shape
}Les classes abstraites peuvent avoir :
- Des méthodes régulières avec des implémentations
- Des constructeurs
- Des propriétés
Les sous-classes héritent de ces membres tout comme avec l'héritage normal. La différence clé est que vous ne pouvez pas créer une instance de la classe abstraite elle-même - vous devez utiliser une sous-classe concrète.
Essayez vous-même
import 'vehicle.dart';
void main() {
// TODO: Créer une Car avec la marque 'Toyota', l'année 2022, et 4 portes
// TODO: Appeler displayInfo() sur la voiture
// TODO: Afficher "Doors: [doors]"
// TODO: Appeler honk() sur la voiture
// TODO: Afficher une ligne vide
// TODO: Créer une Motorcycle avec la marque 'Harley', l'année 2021, et hasSidecar false
// TODO: Appeler displayInfo() sur la moto
// TODO: Afficher "Has sidecar: [hasSidecar]"
// TODO: Appeler revEngine() sur la moto
}
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
1Les bases de la POO
Fichiers externesBibliothèques et importsIntroduction à la POOClasses vs ObjetsLe mot-clé thisMéthodesVariables d'instanceBases des constructeursRécapitulatif - Calculatrice simple4Null Safety
Introduction à la Null SafetyNullable vs Non-NullableLes opérateurs ? et !Le mot-clé late et la Null SafetyLes opérateurs Null-AwareLa Null Safety dans les classesRécapitulatif - Système de profil utilisateur7Classes abstraites et Interfaces
Classes abstraitesMéthodes abstraitesInterfaces en DartInterfaces implicitesImplémentation vs ExtensionInterfaces multiplesRécapitulatif - Calculateur de formes10Collections et Génériques
Aperçu des List, Set et MapCollections Type-SafeClasses génériquesMéthodes génériquesContraintes de généricitéIterable & IteratorRécapitulatif - Stockage générique2Les constructeurs en Dart
Constructeur par défautConstructeurs nommésListes d'initialisationConstructeurs constantsConstructeurs factoryConstructeurs de redirectionRécapitulatif - Shape Builder5Encapsulation
Membres publics vs privésLa convention du préfixe _Visibilité au niveau de la bibliothèqueApprofondissement des Getters & SettersMasquage d'informationsRécapitulatif - Dossiers d'étudiants8Mixins
Introduction aux MixinsCréation de MixinsUtilisation de plusieurs MixinsLe mot-clé on dans les MixinsMixin vs HéritageMixin vs InterfaceRécapitulatif - Système Animal11Méthodes spéciales
Redéfinition de toString()Redéfinition de hashCode & ==Interface ComparableMéthode call()Redéfinition de noSuchMethodRécapitulatif - Collection personnalisée14Patrons de conception Partie 1
Introduction aux patrons de conceptionPatron SingletonPatron FabriquePatron ObservateurPatron Stratégie3Propriétés de classe
Membres d'instance vs statiquesChamps Final & ConstVariables LateMéthodes et champs statiquesGetters et SettersRécapitulatif - Gestionnaire de compte bancaire6Héritage
Bases de l'héritageLe mot-clé superRedéfinition de méthodeL'annotation @overrideLe mot-clé final pour les classesConstructeurs et héritageRécapitulatif - Hiérarchie des employés9Polymorphisme
Bases du polymorphismePolymorphisme via les interfacesVérification de type à l'exécutionLes opérateurs is & asMot-clé covariantRécapitulatif - Processeur de paiement12POO Asynchrone
Futures & async/awaitBases des StreamsStream ControllersConstructeurs asynchronesL'asynchrone dans les méthodes de classeRécapitulatif - Data Fetcher15Patrons de conception Partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Méthode ModèlePatron ÉtatPatron CompositePatron Repository