CodeGym /Blog Java /Ngẫu nhiên /lớp liệt kê trong Java

lớp liệt kê trong Java

Xuất bản trong nhóm
CHÀO! Trong bài viết này, chúng tôi sẽ giới thiệu với bạn về Java Enums . Hãy tưởng tượng rằng bạn được giao nhiệm vụ sau: tạo một lớp thực hiện các ngày trong tuần . Thoạt nhìn, điều này có vẻ khá đơn giản. Mã của bạn sẽ trông giống như thế này:

public class DayOfWeek {

   private String title;

   public DayOfWeek(String title) {
       this.title = title;
   }

   public static void main(String[] args) {
       DayOfWeek dayOfWeek = new DayOfWeek("Saturday");
       System.out.println(dayOfWeek);
   }

   @Override
   public String toString() {
       return "DayOfWeek{" +
               "title='" + title + '\'' +
               '}';
   }
}
Mọi thứ có vẻ ổn, nhưng có một vấn đề: bạn có thể chuyển bất kỳ văn bản nào tới hàm tạo của lớp DayOfWeek . Điều đó có nghĩa là ai đó có thể tạo một ngày trong tuần có tên là "Ếch", "Đám mây" hoặc "azaza322". Đây rõ ràng không phải là hành vi mà chúng ta mong đợi, vì chỉ có 7 ngày thực trong tuần và mỗi ngày đều có một tên cụ thể. Do đó, nhiệm vụ của chúng tôi là bằng cách nào đó giới hạn phạm vi giá trị có thể có cho lớp DayOfWeek . Trước khi Java 1.5 xuất hiện, các nhà phát triển phải độc lập phát minh ra các giải pháp của riêng họ cho vấn đề này, vì ngôn ngữ này không có giải pháp làm sẵn. Vào thời đó, nếu các lập trình viên cần giới hạn số lượng giá trị, họ đã làm như sau:

public class DayOfWeek {

   private String title;

   private DayOfWeek(String title) {
       this.title = title;
   }

   public static DayOfWeek SUNDAY = new DayOfWeek("Sunday");
   public static DayOfWeek MONDAY = new DayOfWeek("Monday");
   public static DayOfWeek TUESDAY = new DayOfWeek("Tuesday");
   public static DayOfWeek WEDNESDAY = new DayOfWeek("Wednesday");
   public static DayOfWeek THURSDAY = new DayOfWeek("Thursday");
   public static DayOfWeek FRIDAY = new DayOfWeek("Friday");
   public static DayOfWeek SATURDAY = new DayOfWeek("Saturday");

   @Override
   public String toString() {
       return "DayOfWeek{" +
               "title='" + title + '\'' +
               '}';
   }
}
Đây là những gì bạn nên chú ý:
  • Hàm tạo là riêng tư. Nếu một hàm tạo được đánh dấu bằng công cụ sửa đổi riêng , thì nó không thể được sử dụng để tạo một đối tượng. Và vì lớp chỉ có một hàm tạo nên không thể tạo đối tượng DayOfWeek nào.

    
    	public class Main {
    
       		public static void main(String[] args) {
          
           			DayOfWeek sunday = new DayOfWeek(); // Error!
       		}
    }
    

  • Tất nhiên, lớp có số lượng đối tượng tĩnh công khai cần thiết , được khởi tạo chính xác (sử dụng tên chính xác của các ngày trong tuần).

    Điều này cho phép các đối tượng này được sử dụng trong các lớp khác.

    
    	public class Person {
    
       		public static void main(String[] args) {
    
           			DayOfWeek sunday = DayOfWeek.SUNDAY;
    
           			System.out.println(sunday);
      		 }
    }
    

    Đầu ra:

    DayOfWeek{title = 'Chủ Nhật'}

Cách tiếp cận này phần lớn giải quyết vấn đề. Chúng ta có 7 ngày trong tuần tùy ý sử dụng và không ai có thể tạo ra những ngày mới. Giải pháp này được đưa ra bởi Joshua Bloch trong cuốn sách Java hiệu quả của ông . Nhân tiện, cuốn sách đó rất hay và phải đọc đối với bất kỳ nhà phát triển Java nào. Cách sử dụng lớp Enum - 2Với việc phát hành Java 1.5, ngôn ngữ này đã có sẵn một giải pháp cho những tình huống như vậy: Java Enums . Enum trong Java cũng là một lớp. Nó được "tinh chỉnh" đặc biệt để giải quyết các vấn đề như thế này, tức là tạo ra một phạm vi giá trị giới hạn nhất định. Những người tạo Java đã có sẵn các ví dụ (ví dụ: C đã có enum ), vì vậy họ có thể tạo biến thể tốt nhất.

Vậy Java Enum là gì?

Hãy xem lại ví dụ DayOfWeek của chúng tôi :

public enum DayOfWeek {

   SUNDAY,
   MONDAY,
   TUESDAY,
   WEDNESDAY,
   THURSDAY,
   FRIDAY,
   SATURDAY
}
Bây giờ có vẻ đơn giản hơn rất nhiều :) Bên trong, Enum của chúng tôi có 7 hằng số tĩnh. Và đó là thứ chúng ta có thể sử dụng để thực hiện một chương trình. Ví dụ: hãy viết một chương trình xác định xem hôm nay một học sinh có cần đi học hay không. Học sinh của chúng tôi sẽ có một lịch trình hàng ngày, được đại diện bởi lớp StudentSchedule :

public class StudentSchedule {

   private DayOfWeek dayOfWeek;
   // ... other fields


   public DayOfWeek getDayOfWeek() {
       return dayOfWeek;
   }

   public void setDayOfWeek(DayOfWeek dayOfWeek) {
       this.dayOfWeek = dayOfWeek;
   }
}
Biến dayOfWeek của đối tượng lịch trình xác định hôm nay là ngày nào. Và đây là lớp sinh viên của chúng ta:

public class Student {

   private StudentSchedule schedule;
   private boolean goToSchool;

   public void wakeUp() {
      
       if (this.schedule.getDayOfWeek() == DayOfWeek.SUNDAY) {
           System.out.println("Hooray, you can sleep more!");
       } else {
           System.out.println("Damn, time for school again :(");
       }
   }
}
Trong phương thức WakeUp() , chúng ta sử dụng Java Enum để xác định học sinh nên làm gì tiếp theo. Chúng tôi thậm chí không cung cấp thông tin chi tiết về từng trường trong DayOfWeek và chúng tôi không cần: rõ ràng các ngày trong tuần sẽ hoạt động như thế nào. Nếu chúng tôi sử dụng nó ở dạng hiện tại, bất kỳ nhà phát triển nào cũng sẽ hiểu điều gì đang xảy ra trong mã của chúng tôi. Một ví dụ khác về sự tiện lợi của Enum là các hằng số của nó có thể được sử dụng với câu lệnh switch. Ví dụ: hãy viết một chương trình cho chế độ ăn kiêng nghiêm ngặt, trong đó các món ăn được lên lịch theo ngày:

public class VeryStrictDiet {
   public void takeLunch(DayOfWeek dayOfWeek) {
       switch (dayOfWeek) {
           case SUNDAY:
               System.out.println("Sunday Dinner! You can even enjoy something a little sweet today.");
               break;
           case MONDAY:
               System.out.println("Lunch for Monday: chicken noodle soup!");
               break;
           case TUESDAY:
               System.out.println("Tuesday, today it's celery soup :(");
               break;
               //... and so on to the end
       }
   }
}
Đây là một trong những lợi thế của Enums so với giải pháp cũ được sử dụng trước Java 1.5 — không thể sử dụng giải pháp cũ với switch . Bạn cần biết gì khác về Enum ? Enum là một lớp thực với tất cả các khả năng mà điều này đòi hỏi. Ví dụ: nếu việc triển khai các ngày trong tuần hiện tại không đủ, bạn có thể thêm các biến, hàm tạo và phương thức vào DayOfWeek :

public enum DayOfWeek {
  
   SUNDAY ("Sunday"),
   MONDAY ("Monday"),
   TUESDAY ("Tuesday"),
   WEDNESDAY ("Wednesday"),
   THURSDAY ("Thursday"),
   FRIDAY ("Friday"),
   SATURDAY ("Saturday");

   private String title;

   DayOfWeek(String title) {
       this.title = title;
   }

   public String getTitle() {
       return title;
   }

   @Override
   public String toString() {
       return "DayOfWeek{" +
               "title='" + title + '\'' +
               '}';
   }
}
Bây giờ các hằng số Enum của chúng ta có trường tiêu đề , trình thu thập và phương thức toString được ghi đè . So với các lớp thông thường, một hạn chế nghiêm trọng được đặt trên Enum — nó không thể được kế thừa. Ngoài ra, liệt kê có phương pháp đặc trưng:
  • values() : trả về một mảng gồm tất cả các giá trị trong Enum :

    
    public static void main(String[] args) {
       		System.out.println(Arrays.toString(DayOfWeek.values()));
    }
    

    Đầu ra:

    [DayOfWeek{title = 'Sunday'}, DayOfWeek{title = 'Monday'}, DayOfWeek{title = 'Tuesday'}, DayOfWeek{title = 'Wednesday'}, DayOfWeek{title = 'Thursday'}, DayOfWeek{title = 'Thứ Sáu'}, DayOfWeek{title = 'Thứ Bảy'}]

  • ordinal() : trả về số thứ tự của hằng số. Việc đánh số bắt đầu từ số không:

    
    	public static void main(String[] args) {
    
       		int sundayIndex = DayOfWeek.SUNDAY.ordinal();
       		System.out.println(sundayIndex);
    }
    

    Đầu ra:

    0

  • valueOf() : trả về đối tượng Enum tương ứng với tên đã truyền:

    
    public static void main(String[] args) {
       DayOfWeek sunday = DayOfWeek.valueOf("SUNDAY");
       System.out.println(sunday);
    }
    

    Đầu ra:

    DayOfWeek{title = 'Chủ Nhật'}

Ghi chú:chúng tôi sử dụng các chữ cái viết hoa để chỉ định các trường Enum . Đây là các hằng số nên chúng sử dụng chữ hoa toàn bộ thay vì camelCase .
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION