Interfaces en Dart
Fait partie de la section Programmation Orientée Objet du Journey Dart de Coddy — leçon 45 sur 110.
Contrairement à de nombreux langages qui possèdent un mot-clé interface dédié, Dart adopte une approche différente. En Dart, chaque classe définit automatiquement une interface. Cette interface se compose de tous les membres publics (méthodes et propriétés) que la classe déclare.
Lorsque vous voulez qu'une classe promette de fournir certaines fonctionnalités sans hériter de l'implémentation, vous utilisez le mot-clé implements :
class Printer {
void printDocument(String content) {
print('Printing: $content');
}
}
class Scanner {
void scan() {
print('Scanning document');
}
}
// MultiFunctionDevice doit implémenter TOUTES les méthodes des deux classes
class MultiFunctionDevice implements Printer, Scanner {
@override
void printDocument(String content) {
print('MFD printing: $content');
}
@override
void scan() {
print('MFD scanning');
}
}La différence clé par rapport à extends est que implements n'hérite d'aucun code. Vous devez fournir votre propre implémentation pour chaque méthode et propriété définie dans l'interface. C'est un contrat : vous promettez que votre classe aura ces capacités, mais vous décidez exactement de la manière dont elles fonctionnent.
Cette approche donne de la flexibilité à Dart. Vous pouvez utiliser des classes abstraites lorsque vous souhaitez définir des interfaces sans implémentation, ou utiliser des classes régulières comme interfaces lorsque cela est pertinent. La leçon suivante explore plus en détail le fonctionnement de ce concept d'« interface implicite ».
Défi
FacileConstruisons un système de lecteur multimédia qui démontre le fonctionnement du mot-clé implements en Dart. Vous allez créer des classes qui servent d'interfaces, puis les implémenter dans un seul appareil combinant plusieurs capacités.
Vous organiserez votre code en deux fichiers :
media.dart: Définissez vos classes d'interface et la classe d'implémentation ici :- Une classe
AudioPlayeravec une méthodeplayAudio(String track)qui affichePlaying audio: [track] - Une classe
VideoPlayeravec une méthodeplayVideo(String title)qui affichePlaying video: [title] - Une classe
SmartTVqui implémente à la foisAudioPlayeretVideoPlayer. Puisqueimplementsn'hérite d'aucun code, vous devez fournir vos propres implémentations pour les deux méthodes. VotreSmartTVdoit afficherSmartTV audio: [track]pour l'audio etSmartTV video: [title]pour la vidéo
- Une classe
main.dart: Importez votre fichier multimédia et démontrez comment une seule classe peut implémenter plusieurs interfaces :- Créez une instance de
SmartTV - Appelez
playAudio('Jazz Collection') - Appelez
playVideo('Nature Documentary')
- Créez une instance de
Remarquez comment SmartTV doit fournir sa propre implémentation pour chaque méthode des deux interfaces - elle n'hérite pas des implémentations originales de AudioPlayer ou VideoPlayer. C'est la différence fondamentale entre implements et extends.
Sortie attendue :
SmartTV audio: Jazz Collection
SmartTV video: Nature DocumentaryAide-mémoire
En Dart, chaque classe définit automatiquement une interface composée de tous ses membres publics. Pour implémenter une interface sans hériter du code, utilisez le mot-clé implements :
class Printer {
void printDocument(String content) {
print('Printing: $content');
}
}
class Scanner {
void scan() {
print('Scanning document');
}
}
// Must implement ALL methods from both classes
class MultiFunctionDevice implements Printer, Scanner {
@override
void printDocument(String content) {
print('MFD printing: $content');
}
@override
void scan() {
print('MFD scanning');
}
}Différences clés par rapport à extends :
implementsn'hérite d'aucune implémentation de code- Vous devez fournir votre propre implémentation pour chaque méthode et propriété
- Une classe peut implémenter plusieurs interfaces
- C'est un contrat promettant que votre classe possédera ces capacités
Essayez vous-même
import 'media.dart';
void main() {
// TODO : Créer une instance de SmartTV
// TODO : Appeler playAudio('Jazz Collection')
// TODO : Appeler playVideo('Nature Documentary')
}
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