Menu
Coddy logo textTech

Operatory is i as

Część sekcji Programowanie obiektowe ścieżki Dart w Coddy. Lekcja 60 z 110.

Chociaż runtimeType podaje dokładny typ, Dart udostępnia dwa operatory, które są praktyczniejsze do sprawdzania typów i rzutowania: is i as.

Operator is sprawdza, czy obiekt jest określonego typu, i zwraca wartość logiczną. W przeciwieństwie do runtimeType, zwraca również true dla typów nadrzędnych:

class Animal {}
class Dog extends Animal {}

void main() {
  Animal pet = Dog();
  
  print(pet is Dog);     // true
  print(pet is Animal);  // true (Dog JEST Animal)
  print(pet is String);  // false
}

Gdy używasz is wewnątrz instrukcji if, Dart automatycznie promuje typ, umożliwiając dostęp do składowych podklasy bez jawnego rzutowania:

void handleAnimal(Animal animal) {
  if (animal is Dog) {
    // Dart wie, że animal jest tutaj typu Dog
    animal.bark();  // Można wywoływać metody specyficzne dla Dog
  }
}

Operator as jawnie rzutuje obiekt na określony typ. Użyj go, gdy masz pewność co do typu:

Animal pet = Dog();
Dog myDog = pet as Dog;  // Rzutuj na Dog
myDog.bark();

Zachowaj ostrożność przy używaniu as — jeśli rzutowanie się nie powiedzie, zostanie zgłoszony wyjątek. Dlatego połączenie is z promocją typu jest często bezpieczniejsze niż bezpośrednie użycie as. Możesz też użyć is!, aby sprawdzić, czy obiekt nie jest określonego typu.

challenge icon

Wyzwanie

Łatwy

Stwórzmy system przetwarzania kształtów, który używa operatorów is i as do rozpoznawania różnych typów kształtów i pracy z nimi. Utworzysz hierarchię kształtów i napiszesz funkcje, które sprawdzają typy oraz bezpiecznie uzyskują dostęp do właściwości specyficznych dla danego typu.

Uporządkujesz kod w dwóch plikach:

  • shapes.dart: Zdefiniuj tutaj hierarchię kształtów:
    • Klasa Shape z właściwością String name i konstruktorem. Dodaj metodę describe(), która wyświetla [name] is a shape
    • Klasa Circle, która rozszerza Shape i ma dodatkową właściwość double radius. Dodaj metodę getCircleInfo(), która wyświetla Circle with radius: [radius]
    • Klasa Rectangle, która rozszerza Shape i ma dodatkowe właściwości double width oraz double height. Dodaj metodę getRectangleInfo(), która wyświetla Rectangle: [width] x [height]
  • main.dart: Zaimportuj plik z kształtami i utwórz funkcję processShape(Shape shape), która:
    • Najpierw wywołuje metodę describe() dla kształtu
    • Używa is, aby sprawdzić, czy kształt jest typu Circle — jeśli tak, używa automatycznej promocji typu, aby wywołać getCircleInfo()
    • Używa is, aby sprawdzić, czy kształt jest typu Rectangle — jeśli tak, używa operatora as, aby rzutować jego typ i wywołać getRectangleInfo()
    • Używa is!, aby sprawdzić, czy kształt NIE jest typu Circle ani Rectangle — jeśli tak, wyświetla Unknown shape type
    Następnie w funkcji main():
    • Utwórz obiekt Circle o nazwie 'Round' i promieniu 5.0, a następnie przekaż go do processShape()
    • Wyświetl pustą linię
    • Utwórz obiekt Rectangle o nazwie 'Box', szerokości 4.0 i wysokości 3.0, a następnie przekaż go do processShape()
    • Wyświetl pustą linię
    • Utwórz obiekt bazowej klasy Shape o nazwie 'Mystery' i przekaż go do processShape()

To wyzwanie pokazuje oba podejścia: użycie is z automatyczną promocją typu dla klasy Circle oraz użycie as do jawnego rzutowania dla klasy Rectangle. Zobaczysz też, jak is! pomaga rozpoznawać kształty, które nie pasują do żadnego konkretnego podtypu.

Oczekiwany wynik:

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

Spróbuj swoich sił

import 'shapes.dart';

// TODO: Utwórz funkcję processShape(Shape shape), która:
// 1. Najpierw wywołuje describe() dla figury
// 2. Używa 'is', aby sprawdzić, czy figura jest typu Circle — jeśli tak, wykorzystuje promocję typu, aby wywołać getCircleInfo()
// 3. Używa 'is', aby sprawdzić, czy figura jest typu Rectangle — jeśli tak, używa operatora 'as' do rzutowania i wywołuje getRectangleInfo()
// 4. Używa 'is!', aby sprawdzić, czy figura NIE jest typu Circle ani Rectangle — jeśli tak, wypisuje "Unknown shape type"

void main() {
  // TODO: Utwórz obiekt Circle o nazwie 'Round' i promieniu 5.0, a następnie przekaż go do processShape()
  
  // TODO: Wypisz pustą linię
  
  // TODO: Utwórz obiekt Rectangle o nazwie 'Box', szerokości 4.0 i wysokości 3.0, a następnie przekaż go do processShape()
  
  // TODO: Wypisz pustą linię
  
  // TODO: Utwórz obiekt bazowej klasy Shape o nazwie 'Mystery', a następnie przekaż go do processShape()
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator Dart online