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.
Wyzwanie
ŁatwyStwó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
Shapez właściwościąString namei konstruktorem. Dodaj metodędescribe(), która wyświetla[name] is a shape - Klasa
Circle, która rozszerzaShapei ma dodatkową właściwośćdouble radius. Dodaj metodęgetCircleInfo(), która wyświetlaCircle with radius: [radius] - Klasa
Rectangle, która rozszerzaShapei ma dodatkowe właściwościdouble widthorazdouble height. Dodaj metodęgetRectangleInfo(), która wyświetlaRectangle: [width] x [height]
- Klasa
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 typuCircle— jeśli tak, używa automatycznej promocji typu, aby wywołaćgetCircleInfo() - Używa
is, aby sprawdzić, czy kształt jest typuRectangle— jeśli tak, używa operatoraas, aby rzutować jego typ i wywołaćgetRectangleInfo() - Używa
is!, aby sprawdzić, czy kształt NIE jest typuCircleaniRectangle— jeśli tak, wyświetlaUnknown shape type
main():- Utwórz obiekt
Circleo nazwie'Round'i promieniu5.0, a następnie przekaż go doprocessShape() - Wyświetl pustą linię
- Utwórz obiekt
Rectangleo nazwie'Box', szerokości4.0i wysokości3.0, a następnie przekaż go doprocessShape() - Wyświetl pustą linię
- Utwórz obiekt bazowej klasy
Shapeo nazwie'Mystery'i przekaż go doprocessShape()
- Najpierw wywołuje metodę
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 typeSpró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()
}
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Programowanie obiektowe
1Podstawy OOP
Pliki zewnętrzneBiblioteki i importyWprowadzenie do OOPKlasy a obiektySłowo kluczowe thisMetodyZmienne instancjiPodstawy konstruktorówPowtórka – prosty kalkulator4Bezpieczeństwo wartości null
Wprowadzenie do bezpieczeństwa wartości nullTypy dopuszczające null i niedopuszczające nullOperatory ? i !Słowo kluczowe late a bezpieczeństwo wartości nullOperatory uwzględniające nullBezpieczeństwo wartości null w klasachPodsumowanie — system profili użytkowników7Klasy abstrakcyjne i interfejsy
Klasy abstrakcyjneMetody abstrakcyjneInterfejsy w DartInterfejsy niejawneImplementowanie a rozszerzanieWiele interfejsówPowtórka — kalkulator kształtów10Kolekcje i typy generyczne
Przegląd List, Set i MapKolekcje bezpieczne typowoKlasy generyczneMetody generyczneOgraniczenia typów generycznychIterable i IteratorPowtórka — generyczne przechowywanie danych13Zaawansowane koncepcje OOP
Kompozycja a dziedziczenieMetody rozszerzająceKlasy wywoływalneKlasy zapieczętowane (Dart 3)Rekordy (Dart 3)Wzorce i dopasowywanie (3.0)Typy wyliczeniowe z metodami16Projekt: Zarządzanie biblioteką
Omówienie projektuKlasy książek i użytkowników2Konstruktory w Dart
Konstruktor domyślnyKonstruktory nazwaneListy inicjalizująceKonstruktory stałeKonstruktory fabryczneKonstruktory przekierowującePodsumowanie — budowanie kształtów5Hermetyzacja
Elementy publiczne a prywatneKonwencja prefiksu _Prywatność na poziomie bibliotekiGettery i settery — szczegółowoUkrywanie informacjiPodsumowanie — dane uczniów8Domieszki
Wprowadzenie do domieszekTworzenie domieszekKorzystanie z wielu domieszekSłowo kluczowe on w domieszkachDomieszka a dziedziczenieDomieszka a interfejsPodsumowanie – system zwierząt11Metody specjalne
Nadpisanie toString()Nadpisanie hashCode i ==Interfejs ComparableMetoda call()Nadpisanie noSuchMethodPodsumowanie — własna kolekcja14Wzorce projektowe, część 1
Wprowadzenie do wzorców projektowychWzorzec SingletonWzorzec FactoryWzorzec ObserverWzorzec Strategy3Właściwości klas
Elementy instancji a elementy statycznePola final i constZmienne inicjalizowane z opóźnieniemMetody i pola statyczneGettery i setteryPowtórzenie – menedżer kont bankowych6Dziedziczenie
Podstawy dziedziczeniaSłowo kluczowe superPrzesłanianie metodAdnotacja @overrideSłowo kluczowe final dla klasKonstruktory i dziedziczeniePowtórzenie – hierarchia pracowników9Polimorfizm
Podstawy polimorfizmuPolimorfizm za pomocą interfejsówSprawdzanie typu w czasie działaniaOperatory is i asSłowo kluczowe covariantPodsumowanie — procesor płatnościPoćwicz samodzielnie: Kompilator Dart online