Generische Klassen
Teil des Abschnitts Objektorientierte Programmierung der Dart-Journey von Coddy. Lektion 65 von 110.
Du hast gesehen, wie Darts integrierte Sammlungen wie List<String> Typparameter verwenden. Jetzt ist es an der Zeit, deine eigenen generischen Klassen zu erstellen, die mit jedem von dir angegebenen Typ funktionieren.
Eine generische Klasse verwendet einen Typparameter (typischerweise T) als Platzhalter für den tatsächlichen Typ, der beim Erstellen einer Instanz bereitgestellt wird:
class Box<T> {
T content;
Box(this.content);
T getContent() => content;
}
void main() {
var stringBox = Box<String>('Hello');
var intBox = Box<int>(42);
print(stringBox.getContent()); // Hello
print(intBox.getContent()); // 42
}Das T fungiert als Typvariable – wenn du Box<String> erstellst, wird jedes T in der Klasse zu String. Dadurch erhältst du Typsicherheit, ohne für jeden Typ separate Klassen schreiben zu müssen.
Du kannst mehrere Typparameter verwenden, wenn deine Klasse mit mehr als einem Typ arbeiten muss:
class Pair<K, V> {
K first;
V second;
Pair(this.first, this.second);
}
void main() {
var pair = Pair<String, int>('age', 25);
print('${pair.first}: ${pair.second}'); // age: 25
}Generische Klassen sind die Grundlage für wiederverwendbaren, typsicheren Code. Anstatt die Logik für verschiedene Typen zu duplizieren oder mit dynamic Typinformationen zu verlieren, kannst du mit Generics flexiblen Code schreiben, den der Compiler dennoch überprüfen kann.
Aufgabe
EinfachErstellen wir ein Geschenkverpackungssystem, das generische Klassen verwendet, um flexible Container für verschiedene Arten von Artikeln zu erstellen. Du erstellst eine generische Klasse Wrapper, die Inhalte beliebigen Typs verpacken kann, sowie eine Klasse GiftBox mit zwei Typparametern, um ein Geschenk mit einer Kartennachricht zu verbinden.
Du organisierst deinen Code in zwei Dateien:
wrapper.dart: Definiere hier deine generischen Klassen:- Eine generische Klasse
Wrapper<T>mit einer EigenschaftT contentund einem Konstruktor. Füge eine Methodeunwrap()hinzu, die den Inhalt zurückgibt, sowie eine Methodedescribe(), dieWrapped: [content]ausgibt - Eine generische Klasse
GiftBox<G, C>mit zwei Eigenschaften:G giftundC card. Füge einen Konstruktor und eine Methodeopen()hinzu, dieGift: [gift]in einer Zeile undCard: [card]in der nächsten Zeile ausgibt
- Eine generische Klasse
main.dart: Importiere deine Wrapper-Datei und demonstriere die generischen Klassen mit verschiedenen Typen:- Erstelle einen
Wrapper<String>mit dem Inhalt'Chocolate'und rufedescribe()auf - Erstelle einen
Wrapper<int>mit dem Inhalt42und rufedescribe()auf - Erstelle einen
Wrapper<double>mit dem Inhalt3.14und rufedescribe()auf - Gib eine leere Zeile aus
- Erstelle einen
GiftBox<String, String>mit dem Geschenk'Teddy Bear'und der Karte'Happy Birthday!'und rufe anschließendopen()auf - Gib eine leere Zeile aus
- Erstelle einen
GiftBox<int, String>mit dem Geschenk100(als Betrag einer Geschenkkarte) und der Karte'Congratulations!'und rufe anschließendopen()auf
- Erstelle einen
Beachte, wie dieselbe Klasse Wrapper nahtlos mit Strings, Ganzzahlen und Gleitkommazahlen funktioniert. Die Klasse GiftBox demonstriert die Verwendung von zwei Typparametern, um verschiedene Typen miteinander zu verbinden – das Geschenk kann einen beliebigen Typ haben, während die Kartennachricht ein String bleibt.
Erwartete Ausgabe:
Wrapped: Chocolate
Wrapped: 42
Wrapped: 3.14
Gift: Teddy Bear
Card: Happy Birthday!
Gift: 100
Card: Congratulations!Probier es selbst
import 'wrapper.dart';
void main() {
// TODO: Erstelle einen Wrapper<String> mit 'Chocolate' und rufe describe() auf
// TODO: Erstelle einen Wrapper<int> mit 42 und rufe describe() auf
// TODO: Erstelle einen Wrapper<double> mit 3.14 und rufe describe() auf
// TODO: Gib eine leere Zeile aus
// TODO: Create a GiftBox<String, String> with gift 'Teddy Bear'
// and card 'Happy Birthday!', then call open()
// TODO: Gib eine leere Zeile aus
// TODO: Erstelle eine GiftBox<int, String> mit gift 100
// and card 'Congratulations!', then call open()
}
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