Menu
CoddyTech

Bản ghi (Java 16+)

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

Khi tạo các lớp đơn giản dùng để chứa dữ liệu, bạn thường phải viết nhiều đoạn code lặp lại: các trường private, hàm khởi tạo, getter, toString(), equals() và hashCode(). Java 16 giới thiệu record để loại bỏ công việc tẻ nhạt này.

record là một lớp đặc biệt dùng để lưu trữ dữ liệu bất biến. Bạn khai báo lớp này bằng từ khóa record, theo sau là danh sách thành phần:

record Person(String name, int age) { }

// Chỉ một dòng đó tự động tạo ra:
// - các trường private final: name và age
// - một hàm khởi tạo (constructor): Person(String name, int age)
// - các phương thức truy cập (accessor methods): name() và age()
// - toString(), equals() và hashCode()

Cách dùng bản ghi rất đơn giản:

Person p = new Person("Alice", 30);
System.out.println(p.name());    // Alice
System.out.println(p.age());     // 30
System.out.println(p);           // Person[name=Alice, age=30]

Lưu ý rằng các phương thức truy cập không dùng tiền tố get: chúng chỉ được đặt tên theo các trường. Record mặc định là final, vì vậy không thể mở rộng chúng. Tất cả các trường cũng đều là final, khiến record vốn bất biến.

Bạn có thể thêm các phương thức tùy chỉnh và ghi đè các phương thức được tạo tự động nếu cần. Bạn cũng có thể thêm bước xác thực trong hàm khởi tạo rút gọn:

record Person(String name, int age) {
    public Person {
        if (age < 0) throw new IllegalArgumentException("Age cannot be negative");
    }
}

Bản ghi rất phù hợp với DTO, phản hồi API hoặc mọi trường hợp bạn cần một vùng chứa dữ liệu đơn giản, bất biến mà không phải viết code rườm rà.

challenge icon

Thử thách

Dễ

Hãy cùng xây dựng hệ thống đặt vé xem phim để khám phá sự tinh gọn của record trong Java. Bạn sẽ thấy record loại bỏ code rườm rà mà vẫn cho phép bạn thêm phương thức tùy chỉnh và bước xác thực.

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

  • Movie.java: Tạo một record đại diện cho một bộ phim với ba thành phần: title (String), genre (String) và durationMinutes (int). Thêm một phương thức tùy chỉnh có tên getFormattedDuration() để trả về thời lượng theo định dạng dễ đọc: [hours]h [minutes]m (ví dụ: 142 phút sẽ thành 2h 22m). Dùng phép chia lấy phần nguyên và phép chia lấy dư để tính số giờ và số phút còn lại.
  • Ticket.java: Tạo một record đại diện cho vé xem phim với ba thành phần: movie (Movie), seatNumber (String) và price (double). Thêm một hàm khởi tạo rút gọn để xác thực giá vé. Nếu giá nhỏ hơn hoặc bằng 0, hãy ném ngoại lệ IllegalArgumentException với thông báo Price must be positive. Đồng thời, thêm một phương thức tùy chỉnh có tên printTicket() để trả về chuỗi nhiều dòng:
    ========== TICKET ==========
    Movie: [movie title]
    Genre: [movie genre]
    Duration: [formatted duration from movie]
    Seat: [seatNumber]
    Price: $[price]
    ============================
  • Main.java: Hoàn thiện hệ thống đặt vé! Bạn sẽ nhận năm đầu vào: tên phim (String), thể loại (String), thời lượng tính bằng phút (int), số ghế (String) và giá vé (double).

    Tạo một record Movie với ba đầu vào đầu tiên, sau đó tạo một record Ticket với phim, số ghế và giá vé. In ra kết quả khi gọi printTicket() trên vé.

Bạn sẽ nhận năm đầu vào theo thứ tự: tên phim, thể loại, thời lượng (phút), số ghế và giá vé.

Hãy để ý record gọn gàng hơn lớp truyền thống đến mức nào: bạn không cần viết hàm khởi tạo, getter, toString(), equals() hay hashCode(). Hàm khởi tạo rút gọn cho phép bạn thêm bước xác thực mà không cần lặp lại các phép gán trường, và bạn vẫn có thể thêm phương thức tùy chỉnh khi cần!

Tự làm thử

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Đọc các giá trị đầu vào
        String title = scanner.nextLine();
        String genre = scanner.nextLine();
        int durationMinutes = Integer.parseInt(scanner.nextLine());
        String seatNumber = scanner.nextLine();
        double price = Double.parseDouble(scanner.nextLine());
        
        // TODO: Tạo bản ghi Movie với title, genre và durationMinutes
        
        // TODO: Tạo bản ghi Ticket với phim, seatNumber và price
        
        // TODO: In vé bằng phương thức printTicket()
        
    }
}
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