Menu
Coddy logo textTech

Оператор instanceof

Часть раздела Объектно-ориентированное программирование путешествия по Java на Coddy. Урок 31 из 87.

В предыдущем уроке было показано, что downcasting может завершиться ошибкой ClassCastException, если объект на самом деле не является типом, к которому вы выполняете приведение. Оператор instanceof решает эту проблему, позволяя проверить тип объекта перед приведением.

Синтаксис прост: object instanceof ClassName возвращает true, если объект является экземпляром этого класса (или любого из его подклассов):

Animal animal = new Dog();

if (animal instanceof Dog) {
    Dog dog = (Dog) animal;
    dog.bark();  // Безопасно вызывать методы, специфичные для Dog
}

Эта проверка предотвращает ошибки во время выполнения, гарантируя, что приведение типов будет успешным. Оператор также возвращает true для родительских типов в иерархии:

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

Начиная с Java 16, вы можете объединить check и cast в один шаг с помощью сопоставления с образцом:

if (animal instanceof Dog dog) {
    dog.bark();  // 'dog' уже приведён и готов к использованию
}

Этот более чистый синтаксис устраняет отдельную строку приведения типа. Обратите внимание, что instanceof возвращает false при проверке с null, поэтому отдельная проверка на null не нужна.

challenge icon

Задание

Легко

Давайте создадим систему проверки транспортных средств, которая использует оператор instanceof для безопасного определения и обработки различных типов транспортных средств. Вы создадите иерархию транспортных средств и напишете код, который проверяет фактический тип каждого транспортного средства перед обращением к его специализированным функциям.

Вы организуете код в четырёх файлах:

  • Vehicle.java: Создайте базовый class, общий для всех транспортных средств. У каждого транспортного средства есть field model (String). Добавьте constructor для его инициализации, getter method getModel() и method inspect(), который выводит: Inspecting vehicle: [model]
  • Car.java: Создайте class, который расширяет Vehicle. У автомобилей есть дополнительный field numDoors (int). Используйте super для инициализации родительского class. Добавьте method checkDoors(), который выводит: [model] has [numDoors] doors
  • Motorcycle.java: Создайте ещё один class, который расширяет Vehicle. У мотоциклов есть field hasSidecar (boolean). Добавьте method checkSidecar(), который в зависимости от значения boolean выводит либо [model] has a sidecar, либо [model] has no sidecar.
  • Main.java: Здесь instanceof становится особенно важным! Вы получите четыре входных значения: модель автомобиля, количество дверей, модель мотоцикла и наличие бокового прицепа (true/false).

    Создайте array ссылок типа Vehicle, содержащий Car и Motorcycle. Затем пройдите в цикле по array и для каждого транспортного средства:

    • Вызовите базовый method inspect()
    • Используйте instanceof, чтобы проверить, является ли оно Car; если да, безопасно выполните downcast и вызовите checkDoors()
    • Используйте instanceof, чтобы проверить, является ли оно Motorcycle; если да, безопасно выполните downcast и вызовите checkSidecar()

Вы получите четыре входных значения: модель автомобиля (String), количество дверей (int), модель мотоцикла (String) и наличие бокового прицепа (boolean).

Ваша программа должна вывести четыре строки: для каждого транспортного средства вы увидите сообщение о проверке, за которым следует проверка, специфичная для его типа. Оператор instanceof гарантирует, что вы вызываете методы Car только для настоящих Car, а методы Motorcycle — только для настоящих Motorcycle, предотвращая возникновение ClassCastException!

Попробуйте сами

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Считать входные данные
        String carModel = scanner.nextLine();
        int numDoors = Integer.parseInt(scanner.nextLine());
        String motorcycleModel = scanner.nextLine();
        boolean hasSidecar = Boolean.parseBoolean(scanner.nextLine());
        
        // TODO: Создать объект Car с carModel и numDoors
        
        // TODO: Создать объект Motorcycle с motorcycleModel и hasSidecar
        
        // TODO: Создать массив ссылок Vehicle, содержащий Car и Motorcycle
        
        // TODO: Пройти по массиву и для каждого vehicle:
        // 1. Вызвать метод inspect()
        // 2. Использовать instanceof, чтобы проверить, является ли это Car, затем выполнить downcast и вызвать checkDoors()
        // 3. Использовать instanceof, чтобы проверить, является ли это Motorcycle, затем выполнить downcast и вызвать checkSidecar()
    }
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование

Потренируйтесь самостоятельно: Онлайн-компилятор Java