Menu
CoddyTech

Chuyển kiểu lên và chuyển kiểu xuống

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 30 trên 87.

Trong bài học trước, bạn đã thấy biến kiểu lớp cha có thể chứa một đối tượng lớp con như thế nào: Animal myPet = new Dog(). Phép gán này được gọi là upcasting, và nó diễn ra tự động vì Dog luôn là một Animal.

Upcasting đi lên trong hệ thống phân cấp kế thừa. Thao tác này diễn ra ngầm và luôn an toàn:

Dog dog = new Dog();
Animal animal = dog;  // Ép kiểu lên tự động

Khi ép kiểu lên, bạn chỉ có thể truy cập các phương thức được định nghĩa trong lớp cha. Các phương thức riêng của lớp con sẽ bị ẩn, dù bên dưới đối tượng vẫn là một Dog.

Ép kiểu xuống chuyển đổi theo hướng ngược lại, chuyển một tham chiếu lớp cha về kiểu lớp con. Việc này cần ép kiểu tường minh vì không phải lúc nào cũng an toàn:

Animal animal = new Dog();  // Ép kiểu lên
Dog dog = (Dog) animal;     // Ép kiểu xuống: cần ép kiểu tường minh
dog.bark();                 // Giờ bạn có thể truy cập các phương thức của Dog

Ép kiểu xuống có rủi ro. Nếu đối tượng không thực sự thuộc kiểu mà bạn đang ép sang, Java sẽ ném ra ClassCastException khi chạy chương trình:

Animal animal = new Cat();
Dog dog = (Dog) animal;  // Biên dịch thành công, nhưng bị lỗi khi chạy!

Trình biên dịch không thể phát hiện lỗi này vì nó chỉ thấy các kiểu đã khai báo. Chỉ khi chương trình chạy, ta mới biết kiểu thực tế của đối tượng. Trong bài học tiếp theo, bạn sẽ học cách kiểm tra kiểu của đối tượng một cách an toàn trước khi ép kiểu xuống.

challenge icon

Thử thách

Dễ

Hãy xây dựng một hệ thống trình phát đa phương tiện thể hiện cách ép kiểu lên và ép kiểu xuống trong thực tế. Bạn sẽ tạo một hệ thống phân cấp các loại phương tiện và luyện tập chuyển đổi giữa tham chiếu của lớp cha và lớp con.

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

  • Media.java: Tạo lớp cơ sở dùng chung cho tất cả các loại phương tiện. Mỗi mục phương tiện có một trường title (String). Thêm hàm khởi tạo để khởi tạo trường này, phương thức getter getTitle() và phương thức play() để in ra: Playing: [title]
  • Song.java: Tạo một lớp kế thừa Media. Bài hát có thêm trường artist (String). Dùng super để khởi tạo lớp cha. Ghi đè play() để in ra: Playing song: [title] by [artist]. Thêm phương thức showArtist() để in ra: Artist: [artist]
  • Podcast.java: Tạo một lớp khác kế thừa Media. Podcast có trường episode (int). Ghi đè play() để in ra: Playing podcast: [title] - Episode [episode]. Thêm phương thức showEpisode() để in ra: Episode: [episode]
  • Main.java: Minh họa cách ép kiểu lên và ép kiểu xuống với các loại phương tiện. Bạn sẽ nhận bốn đầu vào: tiêu đề bài hát, tên nghệ sĩ, tiêu đề podcast và số tập.

    Trước tiên, tạo một Song và ép kiểu lên thành tham chiếu Media. Gọi play() trên tham chiếu này để xem tính đa hình lúc chạy hoạt động.

    Tiếp theo, ép kiểu xuống tham chiếu Media đó trở lại thành Song và gọi showArtist() để truy cập phương thức riêng của lớp con.

    Sau đó, tạo một Podcast và ép kiểu lên thành tham chiếu Media. Gọi play() trên tham chiếu này.

    Cuối cùng, ép kiểu xuống tham chiếu Media đó trở lại thành Podcast và gọi showEpisode().

Bạn sẽ nhận bốn đầu vào: tiêu đề bài hát (String), tên nghệ sĩ (String), tiêu đề podcast (String) và số tập (int).

Đầu ra gồm bốn dòng: hai dòng cho bài hát (kết quả phát và thông tin nghệ sĩ) và hai dòng cho podcast (kết quả phát và thông tin tập). Hãy chú ý cách ép kiểu lên cho phép bạn xử lý đồng nhất các loại phương tiện khác nhau, còn ép kiểu xuống cho phép bạn truy cập những tính năng riêng của chúng!

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 songTitle = scanner.nextLine();
        String artistName = scanner.nextLine();
        String podcastTitle = scanner.nextLine();
        int episodeNumber = scanner.nextInt();
        
        // TODO: Tạo một Song và ép kiểu lên thành tham chiếu Media
        
        // TODO: Gọi play() qua tham chiếu Media (minh họa tính đa hình)
        
        // TODO: Ép kiểu tham chiếu Media xuống lại thành Song
        
        // TODO: Gọi showArtist() qua tham chiếu Song
        
        // TODO: Tạo một Podcast và ép kiểu lên thành tham chiếu Media
        
        // TODO: Gọi play() qua tham chiếu Media
        
        // TODO: Ép kiểu tham chiếu Media xuống lại thành Podcast
        
        // TODO: Gọi showEpisode() qua tham chiếu Podcast
    }
}
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