Die is & as Operatoren
Teil des Abschnitts Objektorientierte Programmierung der Dart-Journey von Coddy — Lektion 60 von 110.
Während runtimeType Ihnen den exakten Typ mitteilt, bietet Dart zwei Operatoren an, die für die Typprüfung und das Casting praktischer sind: is und as.
Der is-Operator prüft, ob ein Objekt von einem bestimmten Typ ist, und gibt einen booleschen Wert zurück. Im Gegensatz zu runtimeType gibt er auch für übergeordnete Typen true zurück:
class Animal {}
class Dog extends Animal {}
void main() {
Animal pet = Dog();
print(pet is Dog); // true
print(pet is Animal); // true (Dog IST ein Animal)
print(pet is String); // false
}Wenn Sie is innerhalb einer if-Anweisung verwenden, führt Dart automatisch eine Typ-Promotion durch, sodass Sie auf Mitglieder der Unterklasse ohne explizite Typumwandlung zugreifen können:
void handleAnimal(Animal animal) {
if (animal is Dog) {
// Dart weiß hier, dass animal ein Dog ist
animal.bark(); // Kann Dog-spezifische Methoden aufrufen
}
}Der as-Operator wandelt ein Objekt explizit in einen bestimmten Typ um. Verwenden Sie ihn, wenn Sie sich über den Typ sicher sind:
Animal pet = Dog();
Dog myDog = pet as Dog; // Umwandlung in Dog
myDog.bark();Seien Sie vorsichtig mit as – wenn der Cast fehlschlägt, wird eine Exception ausgelöst. Deshalb ist die Kombination von is mit Type Promotion oft sicherer als die direkte Verwendung von as. Sie können auch is! verwenden, um zu prüfen, ob ein Objekt nicht einem bestimmten Typ entspricht.
Aufgabe
EinfachLassen Sie uns ein System zur Formverarbeitung erstellen, das die Operatoren is und as verwendet, um verschiedene Formtypen zu identifizieren und mit ihnen zu arbeiten. Sie werden eine Hierarchie von Formen erstellen und Funktionen schreiben, die Typen prüfen und sicher auf typspezifische Eigenschaften zugreifen.
Sie werden Ihren Code in zwei Dateien organisieren:
shapes.dart: Definieren Sie hier Ihre Formenhierarchie:- Eine
Shape-Klasse mit einerString name-Eigenschaft und einem Konstruktor. Fügen Sie eine Methodedescribe()hinzu, die'$name is a shape'ausgibt. - Eine
Circle-Klasse, dieShapeerweitert, mit einer zusätzlichendouble radius-Eigenschaft. Fügen Sie eine MethodegetCircleInfo()hinzu, die'Circle with radius: $radius'ausgibt. - Eine
Rectangle-Klasse, dieShapeerweitert, mit zusätzlichendouble width- unddouble height-Eigenschaften. Fügen Sie eine MethodegetRectangleInfo()hinzu, die'Rectangle: $width x $height'ausgibt.
- Eine
main.dart: Importieren Sie Ihre Shapes-Datei und erstellen Sie eine FunktionprocessShape(Shape shape), die:- Zuerst
describe()auf der Form aufruft. isverwendet, um zu prüfen, ob die Form einCircleist – falls ja, nutzen Sie Type Promotion, umgetCircleInfo()aufzurufen.isverwendet, um zu prüfen, ob die Form einRectangleist – falls ja, verwenden Sie denas-Operator für einen Cast, umgetRectangleInfo()aufzurufen.is!verwendet, um zu prüfen, ob die Form KEINCircleund KEINRectangleist – falls ja, geben Sie'Unknown shape type'aus.
main()-Funktion:- Erstellen Sie einen
Circlenamens'Round'mit dem Radius5.0und übergeben Sie ihn anprocessShape(). - Geben Sie eine Leerzeile aus.
- Erstellen Sie ein
Rectanglenamens'Box'mit der Breite4.0und der Höhe3.0und übergeben Sie es anprocessShape(). - Geben Sie eine Leerzeile aus.
- Erstellen Sie ein Basis-
Shapenamens'Mystery'und übergeben Sie es anprocessShape().
- Zuerst
Diese Herausforderung demonstriert beide Ansätze: die Verwendung von is mit automatischer Type Promotion für den Circle und die Verwendung von as für explizites Casting beim Rectangle. Sie werden auch sehen, wie is! hilft, Formen zu identifizieren, die keinem spezifischen Subtyp entsprechen.
Erwartete Ausgabe:
Round is a shape
Circle with radius: 5.0
Box is a shape
Rectangle: 4.0 x 3.0
Mystery is a shape
Unknown shape typeSpickzettel
Der is-Operator prüft, ob ein Objekt von einem bestimmten Typ ist, und gibt einen booleschen Wert zurück. Er gibt auch true für Elterntypen zurück:
class Animal {}
class Dog extends Animal {}
void main() {
Animal pet = Dog();
print(pet is Dog); // true
print(pet is Animal); // true (Dog IST ein Animal)
print(pet is String); // false
}Wenn Sie is innerhalb einer if-Anweisung verwenden, führt Dart automatisch eine Typ-Promotion (Type Promotion) durch, sodass Sie auf Mitglieder der Unterklasse zugreifen können, ohne explizit casten zu müssen:
void handleAnimal(Animal animal) {
if (animal is Dog) {
// Dart weiß hier, dass animal ein Dog ist
animal.bark(); // Kann Dog-spezifische Methoden aufrufen
}
}Der as-Operator castet ein Objekt explizit in einen bestimmten Typ:
Animal pet = Dog();
Dog myDog = pet as Dog; // Cast zu Dog
myDog.bark();Seien Sie vorsichtig mit as – wenn der Cast fehlschlägt, wird eine Exception ausgelöst. Die Kombination von is mit Typ-Promotion ist oft sicherer als die direkte Verwendung von as.
Verwenden Sie is!, um zu prüfen, ob ein Objekt nicht von einem bestimmten Typ ist:
if (animal is! Dog) {
print("Not a dog");
}Probier es selbst
import 'shapes.dart';
// TODO: Erstelle eine Funktion processShape(Shape shape), die:
// 1. Zuerst describe() für das shape aufruft
// 2. 'is' verwendet, um zu prüfen, ob shape ein Circle ist – falls ja, verwende Type Promotion, um getCircleInfo() aufzurufen
// 3. 'is' verwendet, um zu prüfen, ob shape ein Rectangle ist – falls ja, verwende den 'as'-Operator für einen Cast und rufe getRectangleInfo() auf
// 4. 'is!' verwendet, um zu prüfen, ob shape KEIN Circle und KEIN Rectangle ist – falls ja, gib "Unknown shape type" aus
void main() {
// TODO: Erstelle einen Circle namens 'Round' mit dem Radius 5.0 und übergib ihn an processShape()
// TODO: Gib eine Leerzeile aus
// TODO: Erstelle ein Rectangle namens 'Box' mit der Breite 4.0 und der Höhe 3.0 und übergib es an processShape()
// TODO: Gib eine Leerzeile aus
// TODO: Erstelle ein Basis-Shape namens 'Mystery' und übergib es an processShape()
}
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