Le mot-clé de classe final
Fait partie de la section Programmation Orientée Objet du Journey Dart de Coddy. Leçon 40 sur 110.
Parfois, vous souhaitez empêcher une classe d'être étendue. Le mot-clé final, lorsqu'il est appliqué à une classe, empêche toute autre classe d'en hériter.
final class DatabaseConnection {
String connectionString;
DatabaseConnection(this.connectionString);
void connect() {
print('Connected to $connectionString');
}
}
// Cela provoquerait une erreur de compilation :
// class CustomConnection extends DatabaseConnection { }Marquer une classe comme final est utile lorsque son extension pourrait rompre son comportement prévu ou ses garanties de sécurité. Par exemple, une classe qui gère des ressources sensibles pourrait avoir besoin de s'assurer que ses méthodes ne sont pas redéfinies de manière inattendue.
Dart 3 a également introduit des modificateurs associés : base force les sous-classes à utiliser extends (pas implements), et sealed limite l'héritage à la même bibliothèque. Pour l'instant, concentrez-vous sur final comme le moyen le plus simple de verrouiller complètement une classe.
Utilisez les classes final quand vous êtes certain que la conception de la classe est terminée et que l'héritage ne ferait que causer des problèmes. Cependant, n'en abusez pas - la plupart des classes gagnent à rester ouvertes à l'extension.
Défi
FacileConstruisons un système de configuration sécurisé qui montre quand et pourquoi vous voudriez empêcher l’extension d’une classe. Vous allez créer une classe finale qui gère les paramètres de l’application, en veillant à ce que son comportement ne puisse pas être modifié par héritage.
Vous organiserez votre code en deux fichiers :
config.dart: définissez vos classes de configuration ici :- Une
final class AppConfigqui ne peut pas être étendue. Elle doit avoir une propriétéString appNameet une propriétéString version, un constructeur qui prend les deux valeurs, ainsi qu’une méthodedisplay()qui affiche[appName] v[version] - Une classe
Featureordinaire (non finale) avec une propriétéString nameet une propriétébool enabled, un constructeur pour les deux propriétés, ainsi qu’une méthodestatus()qui affiche[name]: [enabled ? 'ON' : 'OFF'] - Une classe
ExperimentalFeaturequi étendFeatureet ajoute une propriétéString warning. Remplacezstatus()en utilisant@overridepour appeler d’abord la version du parent avecsuper.status(), puis afficherWarning: [warning]
- Une
main.dart: importez votre fichier de configuration et montrez la différence entre les classes finales et les classes ordinaires :- Créez une instance de
AppConfigavec appName'MyApp'et version'2.0.1', puis appelezdisplay() - Affichez une ligne vide
- Créez une instance de
Featureavec name'Dark Mode'et enabledtrue, puis appelezstatus() - Affichez une ligne vide
- Créez une instance de
ExperimentalFeatureavec name'AI Assistant', enabledfalseet warning'May be unstable', puis appelezstatus()
- Créez une instance de
Remarquez que AppConfig est marquée comme final parce que le comportement de sa configuration doit rester cohérent et sécurisé : aucune sous-classe ne doit pouvoir modifier la manière dont les paramètres sont gérés. En revanche, Feature reste ouverte à l’extension, ce qui permet à ExperimentalFeature d’ajouter un comportement spécialisé.
Sortie attendue :
MyApp v2.0.1
Dark Mode: ON
AI Assistant: OFF
Warning: May be unstableEssayez vous-même
import 'config.dart';
void main() {
// TODO: Créer un AppConfig avec appName 'MyApp' et version '2.0.1'
// Ensuite, appeler display()
// TODO: Afficher une ligne vide
// TODO: Créer un Feature avec name 'Dark Mode' et enabled true
// Ensuite, appeler status()
// TODO: Afficher une ligne vide
// TODO: Créer un ExperimentalFeature avec name 'AI Assistant',
// enabled false, et warning 'May be unstable'
// Ensuite, appeler status()
}
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