call()-Methode
Teil des Abschnitts Objektorientierte Programmierung der Dart-Journey von Coddy — Lektion 73 von 110.
Dart hat eine spezielle Methode namens call(), mit der Sie ein Objekt so verwenden können, als wäre es eine Funktion. Wenn eine Klasse eine call()-Methode definiert, können Sie Instanzen dieser Klasse unter Verwendung der Funktionsaufrufsyntax aufrufen.
class Multiplier {
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 - Objekt wie eine Funktion aufrufen
print(triple(5)); // 15
}Anstatt double.call(5) zu schreiben, kannst du einfach double(5) schreiben. Dart ruft automatisch die call()-Methode auf, wenn du Klammern für das Objekt verwendest.
Die call()-Methode kann beliebige Parameter akzeptieren und jeden Typ zurückgeben, genau wie eine reguläre Methode:
class Greeter {
String prefix;
Greeter(this.prefix);
String call(String name, {String punctuation = '!'}) {
return '$prefix, $name$punctuation';
}
}
void main() {
var hello = Greeter('Hello');
print(hello('Alice')); // Hello, Alice!
print(hello('Bob', punctuation: '?')); // Hello, Bob?
}Dieses Muster ist nützlich, wenn Sie Objekte benötigen, die sich wie Funktionen verhalten, aber auch einen Zustand oder eine Konfiguration beibehalten. Es wird häufig zur Erstellung von wiederverwendbaren Operationen, Validatoren oder Formatierern verwendet, die sich Einstellungen zwischen Aufrufen merken müssen.
Aufgabe
EinfachLassen Sie uns ein Textformatierungssystem erstellen, bei dem Formatierungsobjekte direkt wie Funktionen aufgerufen werden können! Sie werden aufrufbare Klassen erstellen, die Text auf verschiedene Arten transformieren und dabei ihre Konfigurationseinstellungen beibehalten.
Sie werden Ihren Code in zwei Dateien organisieren:
formatters.dart: Erstellen Sie zwei aufrufbare Klassen, die Strings transformieren:- Eine
Wrapper-Klasse, die Text mit einem konfigurierbaren Präfix und Suffix umschließt. Sie sollteprefix- undsuffix-Strings speichern, und ihrecall()-Methode sollte einenString textakzeptieren und den mit dem Präfix und Suffix umschlossenen Text zurückgeben. - Eine
Repeater-Klasse, die Text eine konfigurierbare Anzahl von Malen wiederholt. Sie sollte einetimes-Ganzzahl speichern, und ihrecall()-Methode sollte einenString textakzeptieren und den Text so oft wiederholt zurückgeben, getrennt durch Leerzeichen.
- Eine
main.dart: Importieren Sie Ihre Formatierer und demonstrieren Sie, wie diese Objekte genau wie Funktionen verwendet werden können:- Erstellen Sie einen
Wrappermit dem Präfix'['und dem Suffix']' - Erstellen Sie einen weiteren
Wrappermit dem Präfix'***'und dem Suffix'***' - Erstellen Sie einen
Repeater, bei dem times auf3gesetzt ist - Rufen Sie den ersten Wrapper mit
'Hello'auf und geben Sie das Ergebnis aus - Rufen Sie den zweiten Wrapper mit
'Important'auf und geben Sie das Ergebnis aus - Rufen Sie den Repeater mit
'Go'auf und geben Sie das Ergebnis aus - Demonstrieren Sie die Verkettung, indem Sie das Ergebnis des ersten Wrappers (mit
'Nested') an den zweiten Wrapper übergeben und das Ergebnis ausgeben
- Erstellen Sie einen
Beachten Sie, wie Sie Ihre Formatierungsobjekte direkt mit Klammern aufrufen können, genau wie reguläre Funktionen. Die call()-Methode macht dies möglich, und jedes Objekt merkt sich seine Konfiguration zwischen den Anwendungen!
Erwartete Ausgabe:
[Hello]
***Important***
Go Go Go
***[Nested]***Spickzettel
Die Methode call() ermöglicht es Ihnen, ein Objekt so zu verwenden, als wäre es eine Funktion. Wenn eine Klasse eine call()-Methode definiert, können Sie Instanzen dieser Klasse mit der Funktionsaufrufsyntax aufrufen.
class Multiplier {
int factor;
Multiplier(this.factor);
int call(int value) {
return value * factor;
}
}
void main() {
var double = Multiplier(2);
print(double(5)); // 10 - Objekt wie eine Funktion aufrufen
}Anstatt double.call(5) zu schreiben, können Sie einfach double(5) schreiben. Dart ruft automatisch die Methode call() auf, wenn Sie Klammern für das Objekt verwenden.
Die Methode call() kann beliebige Parameter akzeptieren und jeden Typ zurückgeben:
class Greeter {
String prefix;
Greeter(this.prefix);
String call(String name, {String punctuation = '!'}) {
return '$prefix, $name$punctuation';
}
}
void main() {
var hello = Greeter('Hello');
print(hello('Alice')); // Hello, Alice!
print(hello('Bob', punctuation: '?')); // Hello, Bob?
}Dieses Muster ist nützlich, um Objekte zu erstellen, die sich wie Funktionen verhalten, aber auch einen Zustand oder eine Konfiguration zwischen den Aufrufen beibehalten.
Probier es selbst
import 'formatters.dart';
void main() {
// TODO: Erstelle einen Wrapper mit dem Präfix '[' und dem Suffix ']'
// TODO: Erstelle einen weiteren Wrapper mit dem Präfix '***' und dem Suffix '***'
// TODO: Erstelle einen Repeater, bei dem times auf 3 gesetzt ist
// TODO: Rufe den ersten Wrapper mit 'Hello' auf und gib das Ergebnis aus
// TODO: Rufe den zweiten Wrapper mit 'Important' auf und gib das Ergebnis aus
// TODO: Rufe den Repeater mit 'Go' auf und gib das Ergebnis aus
// TODO: Demonstriere die Verkettung, indem du das Ergebnis des ersten Wrappers
// (mit 'Nested') an den zweiten Wrapper übergibst und das Ergebnis ausgibst
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der OOP
Externe DateienBibliotheken & ImportsEinführung in die OOPKlassen vs. ObjekteDas this-SchlüsselwortMethodenInstanzvariablenKonstruktor-GrundlagenWiederholung – Einfacher Taschenrechner4Null-Sicherheit
Einführung in Null-SicherheitNullable vs. Non-NullableDie ? und ! OperatorenLate-Schlüsselwort & Null-SicherheitNull-aware OperatorenNull-Sicherheit in KlassenZusammenfassung – Benutzerprofil-System7Abstrakte Klassen & Interfaces
Abstrakte KlassenAbstrakte MethodenInterfaces in DartImplizite InterfacesImplementieren vs. ErweiternMehrfache InterfacesRückblick – Shape Calculator10Collections & Generics
Überblick über List, Set und MapTypsichere CollectionsGenerische KlassenGenerische MethodenGenerische ConstraintsIterable & IteratorZusammenfassung – Generische Speicherung13Fortgeschrittene OOP-Konzepte
Komposition vs. VererbungExtension MethodsCallable ClassesSealed Classes (Dart 3)Records (Dart 3)Patterns & Matching (3.0)Enums mit Methoden16Projekt: Bibliotheksverwaltung
ProjektübersichtBuch- und Benutzerklassen2Konstruktoren in Dart
Standard-KonstruktorBenannte KonstruktorenInitialisierungslistenKonstante KonstruktorenFactory-KonstruktorenWeiterleitende KonstruktorenZusammenfassung – Shape Builder5Kapselung
Öffentliche vs. private MemberDie _ Präfix-KonventionSichtbarkeit auf Library-EbeneGetter & Setter im DetailInformation HidingRückblick – Schülerdatensätze8Mixins
Einführung in MixinsMixins erstellenMehrere Mixins verwendenDas on-Schlüsselwort in MixinsMixin vs. VererbungMixin vs. InterfaceZusammenfassung - Tiersystem11Spezielle Methoden
toString() überschreibenhashCode & == überschreibenComparable-Interfacecall()-MethodenoSuchMethod überschreibenZusammenfassung – Eigene Collection14Entwurfsmuster Teil 1
Einführung in EntwurfsmusterSingleton-MusterFactory-MusterObserver-MusterStrategy-Muster3Klasseneigenschaften
Instanz- vs. statische MemberFinal & Const FelderLate-VariablenStatische Methoden & FelderGetter und SetterZusammenfassung – Bankkonto-Manager6Vererbung
Grundlagen der VererbungDas super-SchlüsselwortMethoden überschreibenDie @override-AnnotationDas final-Klassen-SchlüsselwortKonstruktoren & VererbungRückblick – Mitarbeiter-Hierarchie9Polymorphismus
Polymorphismus-GrundlagenPolymorphismus über InterfacesTypprüfung zur LaufzeitDie is & as OperatorenDas covariant SchlüsselwortZusammenfassung – Payment Processor