Die Operatoren is & as
Teil des Abschnitts Objektorientierte Programmierung der Dart-Journey von Coddy. Lektion 60 von 110.
Während runtimeType dir den exakten Typ mitteilt, stellt Dart zwei Operatoren bereit, die für die Typprüfung und Typumwandlung 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 du is innerhalb einer if-Anweisung verwendest, stuft Dart den Typ automatisch höher ein, sodass du ohne explizite Typumwandlung auf Member der Unterklasse zugreifen kannst:
void handleAnimal(Animal animal) {
if (animal is Dog) {
// Dart weiß, dass animal hier 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();Sei vorsichtig mit as – wenn die Typumwandlung fehlschlägt, wird eine Ausnahme ausgelöst. Deshalb ist die Kombination von is mit Typ-Promotion oft sicherer, als as direkt zu verwenden. Du kannst auch is! verwenden, um zu prüfen, ob ein Objekt nicht von einem bestimmten Typ ist.
Aufgabe
EinfachLass uns ein System zur Verarbeitung von Formen erstellen, das die Operatoren is und as verwendet, um verschiedene Formtypen zu identifizieren und mit ihnen zu arbeiten. Du erstellst eine Hierarchie von Formen und schreibst Funktionen, die Typen überprüfen und sicher auf typspezifische Eigenschaften zugreifen.
Du organisierst deinen Code in zwei Dateien:
shapes.dart: Definiere hier deine Formen-Hierarchie:- Eine
Shape-Klasse mit einerString name-Eigenschaft und einem Konstruktor. Füge eine Methodedescribe()hinzu, die[name] is a shapeausgibt - Eine
Circle-Klasse, dieShapeerweitert und zusätzlich über einedouble radius-Eigenschaft verfügt. Füge eine MethodegetCircleInfo()hinzu, dieCircle with radius: [radius]ausgibt - Eine
Rectangle-Klasse, dieShapeerweitert und zusätzlich über die Eigenschaftendouble widthunddouble heightverfügt. Füge eine MethodegetRectangleInfo()hinzu, dieRectangle: [width] x [height]ausgibt
- Eine
main.dart: Importiere deine Formendatei und erstelle eine FunktionprocessShape(Shape shape), die:- Zuerst
describe()für die Form aufruft isverwendet, um zu überprüfen, ob die Form einCircleist – falls ja, verwende die Typ-Promotion, umgetCircleInfo()aufzurufenisverwendet, um zu überprüfen, ob die Form einRectangleist – falls ja, verwende den Operatoras, um sie umzuwandeln, und rufegetRectangleInfo()aufis!verwendet, um zu überprüfen, ob die Form KEINCircleund KEINRectangleist – falls ja, gibUnknown shape typeaus
main()-Funktion Folgendes aus:- Erstelle einen
Circlenamens'Round'mit dem Radius5.0und übergib ihn anprocessShape() - Gib eine leere Zeile aus
- Erstelle ein
Rectanglenamens'Box'mit der Breite4.0und der Höhe3.0und übergib es anprocessShape() - Gib eine leere Zeile aus
- Erstelle eine grundlegende
Shapenamens'Mystery'und übergib sie anprocessShape()
- Zuerst
Diese Aufgabe demonstriert beide Ansätze: die Verwendung von is mit automatischer Typ-Promotion für den Circle und die Verwendung von as für eine explizite Typumwandlung beim Rectangle. Du wirst außerdem sehen, wie is! dabei hilft, Formen zu identifizieren, die keinem bestimmten Untertyp 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 typeProbier 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 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