Kiểu enum và phương thức enum
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 50 trên 87.
enum (kiểu liệt kê) là một kiểu lớp đặc biệt đại diện cho một tập hợp hằng số cố định. Thay vì dùng số nguyên hoặc chuỗi tùy ý để biểu diễn các lựa chọn như ngày trong tuần hoặc trạng thái đơn hàng, enum cung cấp các giá trị dễ đọc và an toàn về kiểu dữ liệu.
enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
Day today = Day.MONDAY;
System.out.println(today); // In ra: MONDAYEnum không chỉ là các hằng số đơn giản, chúng là những lớp đầy đủ. Bạn có thể thêm thuộc tính, hàm khởi tạo và phương thức vào enum:
enum Size {
SMALL(10), MEDIUM(20), LARGE(30);
private int price;
Size(int price) {
this.price = price;
}
public int getPrice() {
return price;
}
}
System.out.println(Size.MEDIUM.getPrice()); // In ra: 20Mỗi enum đều có các phương thức tích hợp hữu ích. Phương thức values() trả về một mảng gồm tất cả các hằng số, còn valueOf() chuyển đổi một chuỗi thành hằng số enum tương ứng. Phương thức ordinal() trả về vị trí của hằng số, bắt đầu từ 0:
for (Day d : Day.values()) {
System.out.println(d + " is at position " + d.ordinal());
}
Day day = Day.valueOf("FRIDAY"); // Chuyển chuỗi (string) thành enumEnum phù hợp khi bạn có một tập hợp giá trị cố định đã biết và không thay đổi trong lúc chạy, giúp code an toàn hơn và diễn đạt rõ ràng hơn so với việc dùng các hằng số thông thường.
Thử thách
DễHãy xây dựng một hệ thống đặt món cho quán cà phê để thể hiện sức mạnh của enum có trường, hàm khởi tạo và phương thức. Bạn sẽ tạo một enum CoffeeSize lưu thông tin giá cả và một hệ thống xử lý đơn hàng của khách.
Bạn sẽ sắp xếp code trong ba tệp:
CoffeeSize.java: Tạo một enum biểu thị các cỡ cà phê cùng giá tương ứng. Enum của bạn cần có ba hằng số:SMALL,MEDIUMvàLARGE, với giá lần lượt là2.50,3.50và4.50.Mỗi cỡ cần có một trường
priceriêng tư kiểu double, một hàm khởi tạo để gán giá trị cho trường đó và một phương thứcgetPrice()để lấy giá. Bạn cũng cần thêm phương thứcgetDescription()trả về một chuỗi theo định dạng:[size name] - $[price](ví dụ:SMALL - $2.5)Order.java: Tạo một lớp biểu thị đơn đặt cà phê. Một Order có hai trường riêng tư:customerName(String) vàsize(CoffeeSize). Thêm hàm khởi tạo để khởi tạo cả hai trường và các phương thức getter cho từng trường.Thêm phương thức
getReceipt()trả về một chuỗi nhiều dòng:Order for: [customerName] Size: [size description from getDescription()] Total: $[price from the size]Main.java: Hãy biến quán cà phê của bạn thành hiện thực! Bạn sẽ nhận hai đầu vào: tên khách hàng (String) và tên cỡ cà phê (String như "SMALL", "MEDIUM" hoặc "LARGE").Trước tiên, dùng
CoffeeSize.valueOf()để chuyển chuỗi tên cỡ thành hằng số enum tương ứng. Tạo một Order với tên khách hàng và cỡ cà phê, sau đó in hóa đơn.Sau khi in hóa đơn, hãy in một dòng trống, rồi hiển thị toàn bộ thực đơn bằng cách lặp qua tất cả giá trị
CoffeeSizevới phương thứcvalues(). Với mỗi cỡ, hãy in phần mô tả trên một dòng riêng.
Bạn sẽ nhận hai đầu vào theo thứ tự: tên khách hàng và tên cỡ cà phê (một trong các giá trị "SMALL", "MEDIUM" hoặc "LARGE").
Hãy chú ý cách enum đóng gói cả thông tin về cỡ và giá tương ứng, gọn gàng hơn nhiều so với việc dùng các hằng số riêng lẻ hoặc các con số tùy ý trong code của bạ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 đầu vào
String customerName = scanner.nextLine();
String sizeName = scanner.nextLine();
// TODO: Chuyển sizeName thành enum CoffeeSize bằng valueOf()
// TODO: Tạo một Order với tên khách hàng và kích cỡ
// TODO: In ra hóa đơn
// TODO: In ra một dòng trống
// TODO: Hiển thị toàn bộ thực đơn bằng cách duyệt qua tất cả giá trị CoffeeSize
// Gợi ý: Dùng CoffeeSize.values() để lấy tất cả hằng số enum
}
}
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
1Kiến thức cơ bản về lập trình hướng đối tượng
Tệp bên ngoàiGiới thiệu về lập trình hướng đối tượngLớp và đối tượngTừ khóa thisPhương thứcTrường (thuộc tính)Phương thức khởi tạoNạp chồng phương thức khởi tạoÔn tập: Máy tính đơn giản4Kế thừa
Kế thừa cơ bản (extends)Từ khóa superGhi đè phương thức (@Override)Chuỗi gọi hàm khởi tạoLớp ObjectKế thừa đơn và đa cấpVì sao không hỗ trợ kế thừa nhiều lớpÔn tập: Phân cấp lớp Employee7Phương thức đặc biệt và lớp Object
Phương thức toString()equals() và hashCode()Phương thức clone()compareTo() và ComparableGiao diện ComparatorÔn tập: sắp xếp tùy chỉnh2Bộ điều chỉnh quyền truy cập và đóng gói
Tổng quan về các mức truy cậpPhương thức getter và setterẨn thông tinTừ khóa finalÔn tập: Trình quản lý tài khoản ngân hàng5Tính đa hình
Kiến thức cơ bản về nạp chồng phương thứcGhi đè phương thức (thời gian chạy)Chuyển kiểu lên và chuyển kiểu xuốngToán tử instanceofLớp và phương thức trừu tượngÔn tập: máy tính hình học8Khái niệm OOP nâng cao
Kết hợp và kế thừaKết tập và hợp thànhLớp bên trong, lớp lồng nhau và lớp ẩn danhKiểu enum và phương thức enumBản ghi (Java 16+)Lớp sealed (Java 17+)3Thuộc tính lớp và thành viên tĩnh
Biến của instance và biến tĩnhPhương thức tĩnhKhối tĩnhHằng số (static final)Ôn tập: bộ đếm và tiện ích6Giao diện và lớp trừu tượng
Giới thiệu về giao diệnTriển khai giao diệnTriển khai nhiều giao diệnPhương thức mặc định và tĩnh trong giao diệnLớp trừu tượng và giao diệnGiao diện hàmÔn tập: hệ thống thanh toán9Kiểu tổng quát
Giới thiệu về kiểu tổng quátLớp tổng quátPhương thức tổng quátTham số kiểu có giới hạnKý tự đại diện (?, extends, super)Ôn tập: vùng chứa tổng quát12Mẫu thiết kế, phần 2
Mẫu CommandMẫu AdapterMẫu DecoratorMẫu Template MethodMẫu StateMẫu CompositeMẫu IteratorTự luyện tập: Trình biên dịch Java online