Generische Einschränkungen
Teil des Abschnitts Objektorientierte Programmierung der Dart-Journey von Coddy. Lektion 67 von 110.
Manchmal benötigen Sie einen generischen Typ, der über bestimmte Fähigkeiten verfügt. Wenn Sie beispielsweise Elemente vergleichen oder auf bestimmte Eigenschaften zugreifen möchten, garantiert ein uneingeschränktes T nicht, dass diese Funktionen vorhanden sind. Generische Einschränkungen ermöglichen es Ihnen, Typparameter auf bestimmte Typen oder deren Unterklassen zu beschränken.
Verwenden Sie das Schlüsselwort extends, um einen Typparameter einzuschränken:
class NumberBox<T extends num> {
T value;
NumberBox(this.value);
T doubled() => (value * 2) as T;
}
void main() {
var intBox = NumberBox<int>(5);
var doubleBox = NumberBox<double>(3.5);
print(intBox.doubled()); // 10
print(doubleBox.doubled()); // 7.0
// var stringBox = NumberBox<String>('hi'); // Fehler!
}Da T extends num, weiß der Compiler, dass value numerische Operationen wie die Multiplikation unterstützt. Ohne diese Einschränkung würde der Aufruf von value * 2 fehlschlagen.
Constraints funktionieren auch mit Ihren eigenen Klassenhierarchien:
abstract class Animal {
String get name;
}
class Dog extends Animal {
String get name => 'Dog';
}
class Shelter<T extends Animal> {
List<T> animals = [];
void add(T animal) => animals.add(animal);
void printNames() {
for (var animal in animals) {
print(animal.name); // Sicher: T garantiert, dass 'name' existiert
}
}
}Generische Constraints kombinieren die Flexibilität von Generics mit der Sicherheit zu wissen, welche Operationen für Ihren Typ verfügbar sind.
Aufgabe
EinfachLass uns einen Statistik-Rechner bauen, der nur mit numerischen Typen funktioniert! Du wirst eine generische Klasse mit einer Einschränkung erstellen, die sicherstellt, dass sie nur mit Zahlen verwendet werden kann, was es dir ermöglicht, mathematische Operationen sicher auf den gespeicherten Werten auszuführen.
Du wirst deinen Code in zwei Dateien organisieren:
stats.dart: Erstelle eine generischeStats<T extends num>-Klasse, die eine Liste von numerischen Werten verwaltet:- Eine
List<T>namensvalues, um die Zahlen zu speichern - Ein Konstruktor, der die Liste mit den bereitgestellten Werten initialisiert
- Eine Methode
sum(), die die Summe aller Werte alsnumzurückgibt - Eine Methode
min(), die den kleinsten Wert alsTzurückgibt - Eine Methode
max(), die den größten Wert alsTzurückgibt - Eine Methode
printStats(), welche die Statistiken formatiert anzeigt
- Eine
main.dart: Importiere deine Statistik-Datei und demonstriere die eingeschränkte generische Klasse mit verschiedenen numerischen Typen:- Erstelle ein
Stats<int>mit den Werten[10, 25, 5, 30, 15]und rufeprintStats()auf - Gib eine Leerzeile aus
- Erstelle ein
Stats<double>mit den Werten[3.5, 1.2, 4.8, 2.1]und rufeprintStats()auf
- Erstelle ein
Die Methode printStats() sollte drei Zeilen ausgeben, welche die Summe, das Minimum und das Maximum anzeigen. Da T extends num gilt, kannst du Vergleichsoperatoren und arithmetische Operationen sicher auf die Werte anwenden – etwas, das mit einem uneingeschränkten generischen Typ nicht möglich wäre.
Erwartete Ausgabe:
Sum: 85
Min: 5
Max: 30
Sum: 11.6
Min: 1.2
Max: 4.8Probier es selbst
import 'stats.dart';
void main() {
// TODO: Erstelle ein Stats<int> mit den Werten [10, 25, 5, 30, 15]
// und rufe printStats() auf
// TODO: Drucke eine Leerzeile
// TODO: Erstelle ein Stats<double> mit den Werten [3.5, 1.2, 4.8, 2.1]
// und rufe printStats() 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