Grundlagen des Polymorphismus
Teil des Abschnitts Objektorientierte Programmierung der Dart-Journey von Coddy. Lektion 57 von 110.
Polymorphismus bedeutet „viele Formen“ – es ist die Fähigkeit, Objekte verschiedener Klassen über eine gemeinsame Schnittstelle zu behandeln. Wenn Sie eine Referenz einer Elternklasse haben, kann diese auf jedes Objekt einer Kindklasse verweisen, und die korrekte Methode wird basierend auf dem tatsächlichen Objekttyp aufgerufen.
Das ist leistungsstark, da Sie Code schreiben können, der mit dem Elterntyp arbeitet und dennoch automatisch alle Kindtypen korrekt verarbeitet:
class Animal {
void speak() => print('Some sound');
}
class Dog extends Animal {
@override
void speak() => print('Woof!');
}
class Cat extends Animal {
@override
void speak() => print('Meow!');
}
void main() {
Animal myPet = Dog(); // Elterntyp, Kindobjekt
myPet.speak(); // Ausgabe: Woof!
myPet = Cat(); // Dieselbe Variable, anderes Objekt
myPet.speak(); // Ausgabe: Meow!
}Die Variable myPet ist als Animal deklariert, aber sie enthält ein Dog oder Cat. Wenn speak() aufgerufen wird, schaut Dart zur Laufzeit auf den tatsächlichen Objekttyp und ruft die entsprechende überschriebene Methode auf.
Dies ermöglicht es Ihnen, flexible Funktionen zu schreiben, die mit jeder Unterklasse funktionieren:
void makeAllSpeak(List<Animal> animals) {
for (var animal in animals) {
animal.speak(); // Jedes Tier spricht auf seine eigene Weise
}
}
void main() {
var pets = [Dog(), Cat(), Dog()];
makeAllSpeak(pets);
// Ausgabe: Woof! Meow! Woof!
}Die Funktion muss nichts über Dog oder Cat wissen – sie arbeitet einfach mit Animal. Dies macht Ihren Code erweiterbarer, da das Hinzufügen neuer Tierarten keine Änderungen an bestehenden Funktionen erfordert.
Aufgabe
EinfachLass uns ein Musikinstrumentensystem erstellen, das Polymorphismus in Aktion demonstriert. Du erstellst eine übergeordnete Instrument-Klasse und mehrere Instrumenttypen und schreibst anschließend eine Funktion, die jede Sammlung von Instrumenten gemeinsam spielen lassen kann – ohne deren spezifische Typen zu kennen.
Du organisierst deinen Code in zwei Dateien:
instruments.dart: Definiere hier deine Instrumenthierarchie:- Eine
Instrument-Klasse mit einerString name-Eigenschaft und einem Konstruktor. Füge eine Methodeplay()hinzu, die[name] makes a soundausgibt. - Eine
Guitar-Klasse, dieInstrumenterweitert undplay()überschreibt, um[name] strums melodicallyauszugeben. - Eine
Drum-Klasse, dieInstrumenterweitert undplay()überschreibt, um[name] beats rhythmicallyauszugeben. - Eine
Piano-Klasse, dieInstrumenterweitert undplay()überschreibt, um[name] plays harmoniouslyauszugeben.
performConcert(List<Instrument> instruments), dieConcert begins!ausgibt, anschließend die Liste durchläuft und für jedes Instrumentplay()aufruft und schließlichConcert ends!ausgibt.- Eine
main.dart: Importiere deine Instrumentdatei und demonstriere Polymorphismus, indem du eine gemischte Band erstellst:- Erstelle eine Liste des Typs
List<Instrument>, die eineGuitarnamens'Acoustic', eineDrumnamens'Snare'und einPianonamens'Grand'enthält. - Übergib diese Liste an
performConcert().
- Erstelle eine Liste des Typs
Beachte, wie performConcert() mit dem übergeordneten Typ Instrument arbeitet, während jedes Instrument auf seine eigene einzigartige Weise spielt. Das ist Polymorphismus – derselbe Methodenaufruf erzeugt je nach tatsächlichem Objekttyp ein unterschiedliches Verhalten.
Erwartete Ausgabe:
Concert begins!
Acoustic strums melodically
Snare beats rhythmically
Grand plays harmoniously
Concert ends!Probier es selbst
import 'instruments.dart';
void main() {
// TODO: Erstelle eine List<Instrument>, die Folgendes enthält:
// - Eine Guitar namens 'Acoustic'
// - Eine Drum namens 'Snare'
// - Ein Piano namens 'Grand'
// TODO: Rufe performConcert() mit deiner Liste von Instrumenten 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 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