Classes appelables
Fait partie de la section Programmation Orientée Objet du Journey Dart de Coddy — leçon 84 sur 110.
En Dart, vous pouvez rendre les instances d'une classe appelables comme des fonctions en implémentant la méthode call(). Cela vous permet d'utiliser un objet avec la syntaxe d'appel de fonction — en utilisant des parenthèses directement sur l'instance.
class Multiplier {
final int factor;
Multiplier(this.factor);
int call(int value) {
return value * factor;
}
}
void main() {
var double = Multiplier(2);
var triple = Multiplier(3);
print(double(5)); // 10 - appeler l'objet comme une fonction
print(triple(5)); // 15
}Lorsque vous écrivez double(5), Dart appelle automatiquement la méthode call() avec 5 comme argument. L'objet se comporte comme une fonction tout en conservant son état (le champ factor).
La méthode call() peut avoir n'importe quelle signature - plusieurs paramètres, des paramètres optionnels, ou même retourner différents types :
class Greeter {
final String greeting;
Greeter(this.greeting);
String call(String name, {String punctuation = '!'}) {
return '$greeting, $name$punctuation';
}
}
void main() {
var hello = Greeter('Hello');
print(hello('Alice')); // Hello, Alice!
print(hello('Bob', punctuation: '.')); // Hello, Bob.
}Les classes appelables sont utiles lorsque vous avez besoin d'un comportement semblable à celui d'une fonction combiné à un état ou une configuration. Elles sont couramment utilisées pour créer des opérations réutilisables, des validateurs ou des transformations qui doivent mémoriser des paramètres entre les appels.
Défi
FacileConstruisons un système de formatage de texte en utilisant des classes appelables (callable classes) ! Vous allez créer des objets qui peuvent être appelés comme des fonctions pour transformer du texte de différentes manières, tout en conservant leurs propres paramètres de configuration.
Vous organiserez votre code en deux fichiers :
formatters.dart: Créez deux classes appelables qui transforment le texte :- Une classe
Wrapperqui enveloppe le texte avec un préfixe et un suffixe. Elle doit stocker unString prefixet unString suffix, et lorsqu'elle est appelée avec un paramètreString text, elle doit retourner le texte enveloppé entre le préfixe et le suffixe. - Une classe
Repeaterqui répète le texte un certain nombre de fois. Elle doit stocker une valeurint times, et lorsqu'elle est appelée avec un paramètreString text, elle doit retourner le texte répété ce nombre de fois avec un espace entre chaque répétition.
- Une classe
main.dart: Importez vos formateurs et démontrez le fonctionnement des classes appelables :- Créez un
Wrapperavec le préfixe"["et le suffixe"]" - Créez un autre
Wrapperavec le préfixe"***"et le suffixe"***" - Créez un
Repeaterqui répète 3 fois - Appelez le premier wrapper avec
"Hello"et affichez le résultat - Appelez le deuxième wrapper avec
"Important"et affichez le résultat - Appelez le repeater avec
"Go"et affichez le résultat - Enfin, combinez-les : appelez le premier wrapper avec le résultat de l'appel du repeater avec
"Dart", et affichez le résultat
- Créez un
Remarquez comment chaque objet formateur mémorise sa configuration et peut être appelé directement avec des parenthèses, tout comme une fonction !
Résultat attendu :
[Hello]
***Important***
Go Go Go
[Dart Dart Dart]Aide-mémoire
Les classes peuvent être rendues appelables comme des fonctions en implémentant la méthode call() :
class Multiplier {
final int factor;
Multiplier(this.factor);
int call(int value) {
return value * factor;
}
}
void main() {
var double = Multiplier(2);
print(double(5)); // 10 - appel de l'objet comme une fonction
}La méthode call() peut avoir n'importe quelle signature avec plusieurs paramètres, des paramètres optionnels ou différents types de retour :
class Greeter {
final String greeting;
Greeter(this.greeting);
String call(String name, {String punctuation = '!'}) {
return '$greeting, $name$punctuation';
}
}
void main() {
var hello = Greeter('Hello');
print(hello('Alice')); // Hello, Alice!
print(hello('Bob', punctuation: '.')); // Hello, Bob.
}Les classes appelables sont utiles pour créer un comportement semblable à celui d'une fonction combiné à un état ou une configuration.
Essayez vous-même
import 'formatters.dart';
void main() {
// TODO: Créer un Wrapper avec le préfixe "[" et le suffixe "]"
// TODO: Créer un autre Wrapper avec le préfixe "***" et le suffixe "***"
// TODO: Créer un Repeater qui répète 3 fois
// TODO: Appeler le premier wrapper avec "Hello" et afficher le résultat
// TODO: Appeler le second wrapper avec "Important" et afficher le résultat
// TODO: Appeler le repeater avec "Go" et afficher le résultat
// TODO: Les combiner : appeler le premier wrapper avec le résultat de
// l'appel du repeater avec "Dart", et afficher le résultat
}
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érique13Concepts avancés de la POO
Composition vs HéritageMéthodes d'extensionClasses appelablesClasses scellées (Dart 3)Records (Dart 3)Patterns et Matching (3.0)Enums avec méthodes2Les 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