Methoden überschreiben
Teil des Abschnitts Objektorientierte Programmierung der Dart-Journey von Coddy — Lektion 38 von 110.
Methoden-Überschreiben tritt auf, wenn eine Kindklasse ihre eigene Implementierung einer Methode bereitstellt, die bereits in der Elternklasse existiert. Dies ermöglicht es Unterklassen, geerbtes Verhalten anzupassen, während die gleiche Methodensignatur beibehalten wird.
Wenn Sie eine Methode in einer Kindklasse mit demselben Namen und denselben Parametern wie in der Elternklasse definieren, übernimmt die Version der Kindklasse:
class Animal {
String name;
Animal(this.name);
void speak() {
print('$name makes a sound');
}
}
class Dog extends Animal {
Dog(String name) : super(name);
void speak() {
print('$name barks: Woof!');
}
}
void main() {
var animal = Animal('Generic');
var dog = Dog('Buddy');
animal.speak(); // Generic macht ein Geräusch
dog.speak(); // Buddy bellt: Woof!
}Wenn Sie speak() auf einer Dog-Instanz aufrufen, führt Dart die Version von Dog aus, nicht die von Animal. Die Kindklasse hat die Methode der Elternklasse überschrieben.
Sie können das Überschreiben auch mit super kombinieren, um das Verhalten der Elternklasse zu erweitern, anstatt es zu ersetzen:
class Cat extends Animal {
Cat(String name) : super(name);
void speak() {
super.speak(); // Zuerst die Version der Elternklasse aufrufen
print('$name also purrs');
}
}Dieses Muster ermöglicht es Ihnen, auf bestehender Funktionalität aufzubauen. Die Grundregel ist einfach: Der gleiche Methodenname und die gleichen Parameter in der Kindklasse ersetzen die Implementierung der Elternklasse, wenn sie auf Instanzen der Kindklasse aufgerufen werden.
Aufgabe
EinfachLassen Sie uns ein Benachrichtigungssystem erstellen, das zeigt, wie Kindklassen Methoden der Elternklasse überschreiben können, um das Verhalten anzupassen. Sie werden verschiedene Benachrichtigungstypen erstellen, die Nachrichten jeweils auf ihre eigene, einzigartige Weise zustellen.
Sie werden Ihren Code in zwei Dateien organisieren:
notification.dart: Definieren Sie hier Ihre Benachrichtigungshierarchie:- Eine
Notification-Klasse (die Elternklasse) mit einemString titleund einemString message. Fügen Sie einen Konstruktor hinzu, der beide Werte entgegennimmt, sowie eine Methodesend(), dieNotification: [title] - [message]ausgibt. - Eine
EmailNotification-Klasse, dieNotificationerweitert und eineString recipient-Eigenschaft hinzufügt. Überschreiben Sie diesend()-Methode so, dass sieSending email to [recipient]: [title] - [message]ausgibt. - Eine
PushNotification-Klasse, dieNotificationerweitert und eineString deviceId-Eigenschaft hinzufügt. Überschreiben Sie diesend()-Methode so, dass sie zuerst diesend()-Methode der Elternklasse mittelssuperaufruft und dann in der nächsten ZeilePushed to device: [deviceId]ausgibt.
- Eine
main.dart: Importieren Sie Ihre Benachrichtigungsdatei und demonstrieren Sie das Überschreiben von Methoden in Aktion:- Erstellen Sie eine Basis-
Notificationmit dem Titel'Alert'und der Nachricht'System update available'. - Rufen Sie deren
send()-Methode auf. - Geben Sie eine Leerzeile aus.
- Erstellen Sie eine
EmailNotificationmit dem Titel'Welcome', der Nachricht'Thanks for signing up!'und dem Empfänger'user@example.com'. - Rufen Sie deren
send()-Methode auf. - Geben Sie eine Leerzeile aus.
- Erstellen Sie eine
PushNotificationmit dem Titel'Reminder', der Nachricht'Meeting in 10 minutes'und der deviceId'DEVICE-001'. - Rufen Sie deren
send()-Methode auf.
- Erstellen Sie eine Basis-
Beachten Sie, wie EmailNotification das Verhalten der Elternklasse vollständig ersetzt, während PushNotification es erweitert, indem zuerst super.send() aufgerufen wird. Beide Ansätze sind gültige Wege, um Methoden je nach Bedarf zu überschreiben.
Erwartete Ausgabe:
Notification: Alert - System update available
Sending email to user@example.com: Welcome - Thanks for signing up!
Notification: Reminder - Meeting in 10 minutes
Pushed to device: DEVICE-001Spickzettel
Methoden-Überschreiben (Method Overriding) tritt auf, wenn eine Unterklasse ihre eigene Implementierung einer Methode bereitstellt, die bereits in der Elternklasse existiert. Die Version der Unterklasse ersetzt die der Elternklasse, wenn sie auf Instanzen der Unterklasse aufgerufen wird.
Um eine Methode zu überschreiben, definieren Sie diese in der Unterklasse mit demselben Namen und denselben Parametern:
class Animal {
String name;
Animal(this.name);
void speak() {
print('$name makes a sound');
}
}
class Dog extends Animal {
Dog(String name) : super(name);
void speak() {
print('$name barks: Woof!');
}
}
void main() {
var animal = Animal('Generic');
var dog = Dog('Buddy');
animal.speak(); // Generic makes a sound
dog.speak(); // Buddy barks: Woof!
}Sie können super verwenden, um die Version der Elternklasse aufzurufen und das Verhalten zu erweitern, anstatt es nur zu ersetzen:
class Cat extends Animal {
Cat(String name) : super(name);
void speak() {
super.speak(); // Zuerst die Version der Elternklasse aufrufen
print('$name also purrs');
}
}Probier es selbst
import 'notification.dart';
void main() {
// TODO: Erstelle eine Basis-Notification mit dem Titel 'Alert' und der Nachricht 'System update available'
// Rufe deren send() Methode auf
// TODO: Gib eine Leerzeile aus
// TODO: Erstelle eine EmailNotification mit:
// - title: 'Welcome'
// - message: 'Thanks for signing up!'
// - recipient: 'user@example.com'
// Rufe deren send() Methode auf
// TODO: Gib eine Leerzeile aus
// TODO: Erstelle eine PushNotification mit:
// - title: 'Reminder'
// - message: 'Meeting in 10 minutes'
// - deviceId: 'DEVICE-001'
// Rufe deren send() Methode auf
}
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