Implizite Interfaces
Teil des Abschnitts Objektorientierte Programmierung der Dart-Journey von Coddy. Lektion 46 von 110.
Da jede Dart-Klasse automatisch ein Interface definiert, können Sie jede Klasse als Interface verwenden – sogar konkrete Klassen mit vollständigen Implementierungen. Dies bezeichnen wir als ein implizites Interface.
Betrachten Sie eine Klasse mit Eigenschaften und Methoden:
class Logger {
String prefix = '[LOG]';
void log(String message) {
print('$prefix $message');
}
void clear() {
print('Clearing logs...');
}
}Wenn eine andere Klasse Logger implementiert, muss sie ihre eigene Implementierung für alles bereitstellen – einschließlich der Eigenschaft 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...');
}
}Das ist die entscheidende Erkenntnis: Wenn Sie implements verwenden, sagen Sie „meine Klasse wird die gleiche Form haben“ – die gleichen Methoden und Eigenschaften. Sie erben keinen Code, keine Konstruktoren oder Standardwerte. Sie versprechen lediglich, der Struktur des Interfaces zu entsprechen.
Dies macht implizite Schnittstellen leistungsfähig für die Erstellung austauschbarer Komponenten. Code, der einen Logger erwartet, kann mit jeder Klasse arbeiten, die dessen Schnittstelle implementiert, unabhängig davon, wie diese Implementierung intern funktioniert.
Aufgabe
EinfachLassen Sie uns ein Benachrichtigungssystem erstellen, das zeigt, wie konkrete Klassen als implizite Schnittstellen dienen können. Sie werden eine Basis-Benachrichtigungsklasse erstellen und diese dann auf eine völlig andere Weise implementieren, um zu zeigen, dass implements erfordert, dass Sie alle Member selbst bereitstellen.
Sie werden Ihren Code in zwei Dateien organisieren:
notification.dart: Definieren Sie hier Ihre Benachrichtigungsklassen:- Eine
Notification-Klasse mit einerString channel-Eigenschaft, die auf'default'gesetzt ist, einer Methodesend(String message), die[channel]: [message]ausgibt, und einer MethodegetStatus(), die den String'Notification ready'zurückgibt - Eine
EmailNotification-Klasse, dieNotificationimplementiert. Da Sieimplementsverwenden, müssen Sie Ihre eigenechannel-Eigenschaft bereitstellen (setzen Sie diese auf'email'), Ihre eigenesend()-Methode, dieSending email: [message]ausgibt, und Ihre eigenegetStatus()-Methode, die'Email service active'zurückgibt - Eine
PushNotification-Klasse, dieNotificationimplementiert. Setzen Sie derenchannelauf'push', lassen Siesend()den TextPush alert: [message]ausgeben und lassen SiegetStatus()den Wert'Push service connected'zurückgeben
- Eine
main.dart: Importieren Sie Ihre Benachrichtigungsdatei und demonstrieren Sie, wie verschiedene Klassen dieselbe implizite Schnittstelle mit völlig unterschiedlichem Verhalten implementieren können:- Erstellen Sie eine
EmailNotificationund einePushNotification - Geben Sie für jede Benachrichtigung ihren Status mit
getStatus()aus und rufen Sie dannsend()mit der Nachricht'Hello World'auf - Geben Sie eine Leerzeile zwischen den beiden Benachrichtigungen aus
- Erstellen Sie eine
Denken Sie daran: Wenn Sie implements verwenden, erben Sie keinen Code von Notification. Sie versprechen nur, dass Ihre Klasse dieselbe Form haben wird – dieselben Eigenschaften und Methoden. Jede implementierende Klasse stellt ihre eigene vollständige Implementierung bereit.
Erwartete Ausgabe:
Email service active
Sending email: Hello World
Push service connected
Push alert: Hello WorldProbier es selbst
import 'notification.dart';
void main() {
// TODO: Erstelle eine EmailNotification-Instanz
// TODO: Gib den Status der E-Mail-Benachrichtigung mit getStatus() aus
// TODO: Sende eine Nachricht 'Hello World' über die E-Mail-Benachrichtigung
// TODO: Gib eine Leerzeile aus
// TODO: Erstelle eine PushNotification-Instanz
// TODO: Gib den Status der Push-Benachrichtigung mit getStatus() aus
// TODO: Sende eine Nachricht 'Hello World' über die Push-Benachrichtigung
}
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 Schlüsselwort thisMethodenInstanzvariablenGrundlagen von KonstruktorenRückblick – Einfacher Taschenrechner4Null-Sicherheit
Einführung in die Null-SicherheitNullable vs. Non-NullableDie Operatoren ? und !Late-Schlüsselwort und Null-SicherheitNull-bewusste OperatorenNull-Sicherheit in KlassenRückblick – Benutzers профilsystem7Abstrakte Klassen & Interfaces
Abstrakte KlassenAbstrakte MethodenInterfaces in DartImplizite InterfacesImplementieren vs. ErweiternMehrere InterfacesZusammenfassung – Formrechner10Collections & Generics
Übersicht über List, Set und MapTypsichere CollectionsGenerische KlassenGenerische MethodenGenerische EinschränkungenIterable & IteratorRückblick – Generischer Speicher13Fortgeschrittene OOP-Konzepte
Komposition vs. VererbungErweiterungsmethodenAufrufbare KlassenVersiegelte Klassen (Dart 3)Records (Dart 3)Muster & Matching (3.0)Enums mit Methoden16Projekt: Bibliotheksverwaltung
ProjektübersichtBuch- und Benutzerklassen2Konstruktoren in Dart
StandardkonstruktorBenannte KonstruktorenInitialisierungslistenKonstantenkonstruktorenFactory-KonstruktorenWeiterleitende KonstruktorenRückblick – Shape Builder5Kapselung
Öffentliche vs. private MemberDie _-Präfix-KonventionBibliotheksweite SichtbarkeitTiefergehende Getter & SetterInformationsverbergungRückblick – Studierendendaten8Mixins
Einführung in MixinsMixins erstellenMehrere Mixins verwendenDas Schlüsselwort „on“ in MixinsMixin vs. VererbungMixin vs. SchnittstelleRückblick – Tiersystem11Spezielle Methoden
toString()-ÜberschreibunghashCode- & ==-ÜberschreibungComparable-Schnittstellecall()-MethodenoSuchMethod-ÜberschreibungWiederholung – Benutzerdefinierte Collection14Entwurfsmuster Teil 1
Einführung in EntwurfsmusterSingleton-MusterFabrikmusterBeobachtermusterStrategiemuster17Abschließende Herausforderungen
E-Learning-PlattformBankingsystemSpielcharaktersystemFahrzeugvermietung3Klassen-Eigenschaften
Instanz- vs. statische MemberFinal- und Const-FelderLate-VariablenStatische Methoden und FelderGetter und SetterRückblick – Bankkontoverwaltung6Vererbung
Grundlegende VererbungDas Schlüsselwort superMethodenüberschreibungDie Annotation @overrideDas Schlüsselwort final für KlassenKonstruktoren und VererbungZusammenfassung – Mitarbeiterhierarchie9Polymorphismus
Grundlagen des PolymorphismusPolymorphismus über InterfacesLaufzeit-TypüberprüfungDie Operatoren is & asCovariant-SchlüsselwortZusammenfassung – ZahlungsprozessorÜbe selbstständig: Online-Dart-Compiler