Menu
CoddyTech

Toán tử instanceof

Thuộc phần Lập trình hướng đối tượng trong hành trình Java của Coddy. Bài học 31 trên 87.

Bài học trước cho thấy việc ép kiểu xuống có thể gây ra ClassCastException nếu đối tượng không thực sự thuộc kiểu mà bạn đang ép sang. Toán tử instanceof giúp giải quyết vấn đề này bằng cách cho phép bạn kiểm tra kiểu của đối tượng trước khi ép kiểu.

Cú pháp khá đơn giản: object instanceof ClassName trả về true nếu đối tượng là một instance của lớp đó (hoặc bất kỳ lớp con nào của nó):

Animal animal = new Dog();

if (animal instanceof Dog) {
    Dog dog = (Dog) animal;
    dog.bark();  // Có thể gọi các phương thức riêng của Dog một cách an toàn
}

Kiểm tra này ngăn lỗi khi chạy bằng cách đảm bảo phép ép kiểu sẽ thành công. Toán tử này cũng trả về true với các kiểu lớp cha trong hệ thống phân cấp:

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

Kể từ Java 16, bạn có thể kết hợp việc kiểm tra và ép kiểu trong một bước bằng cách sử dụng đối sánh mẫu:

if (animal instanceof Dog dog) {
    dog.bark();  // 'dog' đã được ép kiểu và sẵn sàng để dùng
}

Cú pháp gọn hơn này loại bỏ dòng ép kiểu riêng. Lưu ý rằng instanceof trả về false khi kiểm tra với null, vì vậy bạn không cần kiểm tra null riêng.

challenge icon

Thử thách

Dễ

Hãy xây dựng một hệ thống kiểm tra phương tiện sử dụng toán tử instanceof để nhận diện và xử lý an toàn các loại phương tiện khác nhau. Bạn sẽ tạo một hệ thống phân cấp phương tiện và viết code kiểm tra kiểu thực tế của từng phương tiện trước khi truy cập các tính năng riêng của nó.

Bạn sẽ sắp xếp code trong bốn tệp:

  • Vehicle.java: Tạo lớp cơ sở dùng chung cho tất cả phương tiện. Mỗi phương tiện có trường model (String). Thêm hàm khởi tạo để thiết lập trường này, phương thức getter getModel() và phương thức inspect() để in ra: Inspecting vehicle: [model]
  • Car.java: Tạo một lớp kế thừa Vehicle. Ô tô có thêm trường numDoors (int). Dùng super để khởi tạo lớp cha. Thêm phương thức checkDoors() để in ra: [model] has [numDoors] doors
  • Motorcycle.java: Tạo một lớp khác kế thừa Vehicle. Xe máy có trường hasSidecar (boolean). Thêm phương thức checkSidecar() để in ra [model] has a sidecar hoặc [model] has no sidecar tùy theo giá trị boolean.
  • Main.java: Đây là lúc instanceof trở nên thiết yếu! Bạn sẽ nhận bốn đầu vào: mẫu xe ô tô, số cửa, mẫu xe máy và xe máy có thùng phụ hay không (true/false).

    Tạo một mảng các tham chiếu Vehicle chứa một Car và một Motorcycle. Sau đó lặp qua mảng và thực hiện các thao tác sau với từng phương tiện:

    • Gọi phương thức cơ sở inspect()
    • Dùng instanceof để kiểm tra xem đó có phải là Car không. Nếu đúng, ép kiểu xuống một cách an toàn rồi gọi checkDoors()
    • Dùng instanceof để kiểm tra xem đó có phải là Motorcycle không. Nếu đúng, ép kiểu xuống một cách an toàn rồi gọi checkSidecar()

Bạn sẽ nhận bốn đầu vào: mẫu xe ô tô (String), số cửa (int), mẫu xe máy (String) và có thùng phụ hay không (boolean).

Đầu ra gồm bốn dòng. Với mỗi phương tiện, bạn sẽ thấy thông báo kiểm tra, sau đó là phần kiểm tra riêng theo loại phương tiện. Toán tử instanceof đảm bảo bạn chỉ gọi các phương thức của Car trên đối tượng Car thực tế và các phương thức của Motorcycle trên đối tượng Motorcycle thực tế, nhờ đó tránh được mọi ClassCastException!

Tự làm thử

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Đọc dữ liệu đầu vào
        String carModel = scanner.nextLine();
        int numDoors = Integer.parseInt(scanner.nextLine());
        String motorcycleModel = scanner.nextLine();
        boolean hasSidecar = Boolean.parseBoolean(scanner.nextLine());
        
        // TODO: Tạo đối tượng Car với carModel và numDoors
        
        // TODO: Tạo đối tượng Motorcycle với motorcycleModel và hasSidecar
        
        // TODO: Tạo mảng các tham chiếu Vehicle chứa Car và Motorcycle
        
        // TODO: Duyệt qua mảng và với mỗi phương tiện:
        // 1. Gọi phương thức inspect()
        // 2. Dùng instanceof để kiểm tra xem đó có phải là Car không, sau đó ép kiểu xuống và gọi checkDoors()
        // 3. Dùng instanceof để kiểm tra xem đó có phải là Motorcycle không, sau đó ép kiểu xuống và gọi checkSidecar()
    }
}
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Lập trình hướng đối tượng

Tự luyện tập: Trình biên dịch Java online