Menu
Coddy logo textTech

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.

challenge icon

Aufgabe

Einfach

Lassen 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 einer String name-Eigenschaft und einem Konstruktor. Fügen Sie eine Methode describe() hinzu, die '$name is a shape' ausgibt.
    • Eine Circle-Klasse, die Shape erweitert, mit einer zusätzlichen double radius-Eigenschaft. Fügen Sie eine Methode getCircleInfo() hinzu, die 'Circle with radius: $radius' ausgibt.
    • Eine Rectangle-Klasse, die Shape erweitert, mit zusätzlichen double width- und double height-Eigenschaften. Fügen Sie eine Methode getRectangleInfo() hinzu, die 'Rectangle: $width x $height' ausgibt.
  • main.dart: Importieren Sie Ihre Shapes-Datei und erstellen Sie eine Funktion processShape(Shape shape), die:
    • Zuerst describe() auf der Form aufruft.
    • is verwendet, um zu prüfen, ob die Form ein Circle ist – falls ja, nutzen Sie Type Promotion, um getCircleInfo() aufzurufen.
    • is verwendet, um zu prüfen, ob die Form ein Rectangle ist – falls ja, verwenden Sie den as-Operator für einen Cast, um getRectangleInfo() aufzurufen.
    • is! verwendet, um zu prüfen, ob die Form KEIN Circle und KEIN Rectangle ist – falls ja, geben Sie 'Unknown shape type' aus.
    Dann in Ihrer main()-Funktion:
    • Erstellen Sie einen Circle namens 'Round' mit dem Radius 5.0 und übergeben Sie ihn an processShape().
    • Geben Sie eine Leerzeile aus.
    • Erstellen Sie ein Rectangle namens 'Box' mit der Breite 4.0 und der Höhe 3.0 und übergeben Sie es an processShape().
    • Geben Sie eine Leerzeile aus.
    • Erstellen Sie ein Basis-Shape namens 'Mystery' und übergeben Sie es an processShape().

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 type

Spickzettel

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()
}
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung