Menu
Coddy logo textTech

Operator instanceof

Część sekcji Programowanie obiektowe ścieżki Java w Coddy. Lekcja 31 z 87.

Poprzednia lekcja pokazała, że rzutowanie w dół może zakończyć się błędem ClassCastException, jeśli obiekt w rzeczywistości nie jest typu, na który go rzutujesz. Operator instanceof rozwiązuje ten problem, umożliwiając sprawdzenie typu obiektu przed rzutowaniem.

Składnia jest prosta: object instanceof ClassName zwraca true, jeśli obiekt jest instancją tej klasy (lub którejś z jej podklas):

Animal animal = new Dog();

if (animal instanceof Dog) {
    Dog dog = (Dog) animal;
    dog.bark();  // Można bezpiecznie wywoływać metody specyficzne dla Dog
}

To sprawdzenie zapobiega błędom czasu wykonania, upewniając się, że rzutowanie się powiedzie. Operator zwraca również true dla typów nadrzędnych w hierarchii:

Dog dog = new Dog();
System.out.println(dog instanceof Dog);     // true
System.out.println(dog instanceof Animal);  // true
System.out.println(dog instanceof Object);  // true

Od Java 16 możesz połączyć sprawdzenie i rzutowanie w jednym kroku, używając dopasowywania do wzorca:

if (animal instanceof Dog dog) {
    dog.bark();  // 'dog' jest już rzutowany i gotowy do użycia
}

Ta czytelniejsza składnia eliminuje osobną linię rzutowania. Zauważ, że instanceof zwraca false, gdy jest sprawdzane dla null, więc nie potrzebujesz osobnego sprawdzenia wartości null.

challenge icon

Wyzwanie

Łatwy

Zbudujmy system kontroli pojazdów, który używa operatora instanceof do bezpiecznego rozpoznawania i obsługi różnych typów pojazdów. Utworzysz hierarchię pojazdów i napiszesz kod, który sprawdza rzeczywisty typ każdego pojazdu przed uzyskaniem dostępu do jego wyspecjalizowanych funkcji.

Rozmieścisz swój kod w czterech plikach:

  • Vehicle.java: Utwórz klasę bazową wspólną dla wszystkich pojazdów. Każdy pojazd ma pole model (String). Dodaj konstruktor, który je inicjalizuje, metodę pobierającą wartość getModel() oraz metodę inspect(), która wyświetla: Inspecting vehicle: [model]
  • Car.java: Utwórz klasę rozszerzającą Vehicle. Samochody mają dodatkowe pole numDoors (int). Użyj super, aby zainicjalizować klasę nadrzędną. Dodaj metodę checkDoors(), która wyświetla: [model] has [numDoors] doors
  • Motorcycle.java: Utwórz kolejną klasę rozszerzającą Vehicle. Motocykle mają pole hasSidecar (boolean). Dodaj metodę checkSidecar(), która wyświetla [model] has a sidecar albo [model] has no sidecar, w zależności od wartości logicznej.
  • Main.java: To właśnie tutaj instanceof staje się niezbędny! Otrzymasz cztery dane wejściowe: model samochodu, liczbę drzwi, model motocykla oraz informację, czy ma boczny wózek (true/false).

    Utwórz tablicę odwołań typu Vehicle, zawierającą obiekt Car i obiekt Motorcycle. Następnie przejdź pętlą przez tablicę i dla każdego pojazdu:

    • Wywołaj bazową metodę inspect()
    • Użyj instanceof, aby sprawdzić, czy jest to Car — jeśli tak, bezpiecznie rzutuj typ w dół i wywołaj checkDoors()
    • Użyj instanceof, aby sprawdzić, czy jest to Motorcycle — jeśli tak, bezpiecznie rzutuj typ w dół i wywołaj checkSidecar()

Otrzymasz cztery dane wejściowe: model samochodu (String), liczbę drzwi (int), model motocykla (String) oraz informację o tym, czy ma boczny wózek (boolean).

Wynik powinien zawierać cztery wiersze — dla każdego pojazdu zobaczysz komunikat o jego kontroli, a po nim sprawdzenie właściwe dla jego typu. Operator instanceof gwarantuje, że metody Car będą wywoływane tylko dla obiektów Car, a metody Motorcycle tylko dla obiektów Motorcycle, zapobiegając wystąpieniu wyjątku ClassCastException!

Spróbuj swoich sił

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Wczytaj dane wejściowe
        String carModel = scanner.nextLine();
        int numDoors = Integer.parseInt(scanner.nextLine());
        String motorcycleModel = scanner.nextLine();
        boolean hasSidecar = Boolean.parseBoolean(scanner.nextLine());
        
        // TODO: Utwórz obiekt Car z carModel i numDoors
        
        // TODO: Utwórz obiekt Motorcycle z motorcycleModel i hasSidecar
        
        // TODO: Utwórz tablicę referencji typu Vehicle zawierającą obiekty Car i Motorcycle
        
        // TODO: Przejdź przez tablicę i dla każdego pojazdu:
        // 1. Wywołaj metodę inspect()
        // 2. Użyj instanceof, aby sprawdzić, czy to Car, a następnie rzutuj na Car i wywołaj checkDoors()
        // 3. Użyj instanceof, aby sprawdzić, czy to Motorcycle, a następnie rzutuj na Motorcycle i wywołaj checkSidecar()
    }
}
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 Java online