Interfaces implicites
Fait partie de la section Programmation Orientée Objet du Journey Dart de Coddy. Leçon 46 sur 110.
Puisque chaque classe Dart définit automatiquement une interface, vous pouvez utiliser n'importe quelle classe comme une interface - même des classes concrètes avec des implémentations complètes. C'est ce que nous appelons une interface implicite.
Considérez une classe avec des propriétés et des méthodes :
class Logger {
String prefix = '[LOG]';
void log(String message) {
print('$prefix $message');
}
void clear() {
print('Clearing logs...');
}
}Lorsqu'une autre classe implémente Logger, elle doit fournir sa propre implémentation pour tout - y compris la propriété prefix :
class FileLogger implements Logger {
@override
String prefix = '[FILE]';
@override
void log(String message) {
print('$prefix Writing to file: $message');
}
@override
void clear() {
print('Deleting log file...');
}
}C'est l'idée clé : lorsque vous utilisez implements, vous dites « ma classe aura la même forme » — les mêmes méthodes et propriétés. Vous n'héritez d'aucun code, constructeur ou valeur par défaut. Vous promettez seulement de respecter la structure de l'interface.
Cela rend les interfaces implicites puissantes pour la création de composants interchangeables. Le code qui attend un Logger peut fonctionner avec n'importe quelle classe qui implémente son interface, quelle que soit la manière dont cette implémentation fonctionne en interne.
Défi
FacileConstruisons un système de notifications qui montre comment des classes concrètes peuvent servir d’interfaces implicites. Vous allez créer une classe de base pour les notifications, puis l’implémenter d’une manière complètement différente, afin de montrer que implements vous oblige à fournir vous-même tous les membres.
Vous allez organiser votre code en deux fichiers :
notification.dart: définissez ici vos classes de notification :- Une classe
Notificationavec une propriétéString channeldéfinie sur'default', une méthodesend(String message)qui affiche[channel]: [message], et une méthodegetStatus()qui renvoie la chaîne'Notification ready' - Une classe
EmailNotificationqui implémenteNotification. Comme vous utilisezimplements, vous devez fournir votre propre propriétéchannel(définissez-la sur'email'), votre propre méthodesend()qui afficheSending email: [message], ainsi que votre propre méthodegetStatus()qui renvoie'Email service active' - Une classe
PushNotificationqui implémenteNotification. Définissez sa propriétéchannelsur'push', faites en sorte quesend()affichePush alert: [message], et faites en sorte quegetStatus()renvoie'Push service connected'
- Une classe
main.dart: importez votre fichier de notifications et montrez comment différentes classes peuvent implémenter la même interface implicite avec des comportements complètement différents :- Créez une instance de
EmailNotificationet une instance dePushNotification - Pour chaque notification, affichez son état à l’aide de
getStatus(), puis appelezsend()avec le message'Hello World' - Affichez une ligne vide entre les deux notifications
- Créez une instance de
Souvenez-vous : lorsque vous utilisez implements, vous n’héritez d’aucun code de Notification. Vous promettez seulement que votre classe aura la même structure : les mêmes propriétés et méthodes. Chaque classe implémentée fournit sa propre implémentation complète.
Sortie attendue :
Email service active
Sending email: Hello World
Push service connected
Push alert: Hello WorldEssayez vous-même
import 'notification.dart';
void main() {
// TODO: Créer une instance de EmailNotification
// TODO: Afficher le statut de la notification par e-mail en utilisant getStatus()
// TODO: Envoyer un message 'Hello World' en utilisant la notification par e-mail
// TODO: Afficher une ligne vide
// TODO: Créer une instance de PushNotification
// TODO: Afficher le statut de la notification push en utilisant getStatus()
// TODO: Envoyer un message 'Hello World' en utilisant la notification push
}
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