JavaRush /จาวาบล็อก /Random-TH /อีนัมในภาษา Java ตัวอย่างการปฏิบัติ การเพิ่มตัวสร้างและวิ...

อีนัมในภาษา Java ตัวอย่างการปฏิบัติ การเพิ่มตัวสร้างและวิธีการ

เผยแพร่ในกลุ่ม
สวัสดี! วันนี้เราจะพูดถึงประเภทข้อมูลพิเศษใน Java - Enum(ย่อมาจาก enumeration) คุณสมบัติของพวกเขาคืออะไร? ลองจินตนาการว่าเราต้องใช้เวลาหลายเดือนในโปรแกรม เอนัม.  ตัวอย่างการปฏิบัติ  การเพิ่มตัวสร้างและวิธีการ - 1ดูเหมือนว่าปัญหาคืออะไร? คุณเพียงแค่ต้องพิจารณาว่าเดือนใดมีคุณสมบัติใดบ้าง บางทีเราอาจจำเป็นต้องทราบชื่อเดือนและจำนวนวันในเดือนนั้นก่อน วิธีแก้ปัญหาดูค่อนข้างง่าย:
public class Month {

   private String name;
   private int daysCount;

   public Month(String name, int daysCount) {
       this.name = name;
       this.daysCount = daysCount;
   }

   public String getName() {
       return name;
   }

   public void setName(String name) {
       this.name = name;
   }

   public int getDaysCount() {
       return daysCount;
   }

   public void setDaysCount(int daysCount) {
       this.daysCount = daysCount;
   }

   @Override
   public String toString() {
       return "Month{" +
               "name='" + name + '\'' +
               ", daysCount=" + daysCount +
               '}';
   }
}
ขอครบชุด! เรามีคลาสMonth, ฟิลด์ที่จำเป็น, getters-setters, toString(). เว้นแต่equals()จะhashCode()ต้องเติมให้มีความสุขเต็มที่ :) อย่างไรก็ตาม เรามีปัญหาทางความคิดอยู่ ดังที่คุณอาจจำได้ ข้อดีหลักประการหนึ่งของ OOP คือทำให้การสร้างแบบจำลองเอนทิตีในโลกแห่งความเป็นจริงเป็นเรื่องง่าย เก้าอี้ รถยนต์ ดาวเคราะห์ แนวคิดทั้งหมดนี้จากชีวิตประจำวันสามารถนำเสนอในโปรแกรมโดยใช้นามธรรมได้อย่างง่ายดาย ปัญหาคือบางเอนทิตีในโลกแห่งความเป็นจริงมีความหมายที่จำกัดอย่างเคร่งครัด ในหนึ่งปีมีเพียง 4 ฤดูเท่านั้น โน้ตดนตรีมีเพียง 7 ตัวเท่านั้น ในปฏิทินมีเพียง 12 เดือนเท่านั้น Ocean มีเพื่อนเพียง 11 คนเท่านั้น (แม้ว่าจะเป็นเรื่องที่ถกเถียงกันอยู่ก็ตาม :)) กล่าวอีกนัยหนึ่ง คลาส Java ปกติไม่สามารถจำลองเอนทิตีเหล่านี้และเคารพข้อจำกัดตามธรรมชาติของพวกมันได้ ชั้นเรียนของเราMonthมีสาขาที่จำเป็นทั้งหมด แต่ถ้าโปรแกรมเมอร์คนอื่นใช้มัน จะไม่มีใครหยุดเขาจากการสร้างวัตถุที่บ้าคลั่งโดยสิ้นเชิง:
public class Main {

   Month month1 = new Month("lolkek", 322);
   Month month2 = new Month("yahoooooooooooo", 12345);

}
หากปรากฏอยู่ในโปรแกรมคงหาตัวคนร้ายได้ไม่ง่ายแน่! ในแง่หนึ่ง โปรแกรมเมอร์ที่สร้างวัตถุอาจเข้าใจว่าชั้นเรียนMonthหมายถึง "เดือนของปี" และไม่ได้เขียนเรื่องไร้สาระเช่นนั้น ในทางกลับกัน เขาแค่ใช้ประโยชน์จากโอกาสที่นักออกแบบชั้นเรียนมอบให้เขา ฉันสามารถกำหนดชื่อและจำนวนวันได้หรือไม่? พระองค์ทรงแต่งตั้งไว้ จะทำอย่างไรในสถานการณ์เช่นนี้? ก่อนการเปิดตัวภาษา Java เวอร์ชัน 1.5 โปรแกรมเมอร์ต้องพูดอย่างตรงไปตรงมาออกไป :) ในสมัยนั้นพวกเขาสร้างโครงสร้างต่อไปนี้:
public class Month {

   private String name;
   private int daysCount;

   private Month(String name, int daysCount) {
       this.name = name;
       this.daysCount = daysCount;
   }

   public static Month JANUARY = new Month("Январь", 31);
   public static Month FEBRUARY = new Month("Февраль", 28);
   public static Month MARCH = new Month("Март", 31);

   @Override
   public String toString() {
       return "Month{" +
               "name='" + name + '\'' +
               ", daysCount=" + daysCount +
               '}';
   }
}
ที่นี่เราได้ลดความซับซ้อนของจำนวนเดือนลงเป็นสามเดือนแทนที่จะเป็นสิบสองเพื่อให้ตัวอย่างสั้นลง การออกแบบดังกล่าวทำให้สามารถแก้ไขปัญหาได้ ตัวเลือกสำหรับวัตถุที่สร้างขึ้นถูกจำกัดโดยตัวสร้างส่วนตัว:
private Month(String name, int daysCount) {
       this.name = name;
       this.daysCount = daysCount;
   }
โปรแกรมเมอร์ที่ใช้คลาสไม่สามารถสร้างไฟล์Month. พวกเขาถูกบังคับให้ใช้อ็อบเจ็กต์คงที่สุดท้ายที่ได้รับจากผู้พัฒนาคลาส มันดูเหมือนสิ่งนี้:
public class Main {

   public static void main(String[] args) {

       Month january = Month.JANUARY;
       System.out.println(january);
   }

}
อย่างไรก็ตาม นักพัฒนา Java สังเกตเห็นปัญหาที่มีอยู่แล้ว แน่นอนว่าเป็นเรื่องดีที่โปรแกรมเมอร์สามารถคิดวิธีแก้ปัญหาโดยใช้เครื่องมือที่มีในภาษานั้นได้ แต่มันก็ดูไม่ง่ายนัก! จำเป็นต้องมีวิธีแก้ปัญหาที่ชัดเจน สามารถเข้าถึงได้แม้กระทั่งผู้เริ่มต้น เป็นเช่นนี้ . ปรากฏใน Java Enum. โดยพื้นฐานแล้วEnumมันเป็นคลาส Java ที่ให้ชุดของอ็อบเจ็กต์ค่าที่จำกัด นี่คือสิ่งที่ดูเหมือน:
public enum Month {

   JANUARY,
   FEBRUARY,
   MARCH
}
ในคำจำกัดความ เราระบุว่าEnumนี่คือคลาส Java แต่นี่เป็นเรื่องจริงหรือไม่ ใช่ และเราสามารถตรวจสอบได้ ลองยกตัวอย่างการสืบทอดของเราenum Monthจากคลาสอื่น:
public abstract class AbstractMonth {
}

//ошибка! No extends clause allowed to enum
public enum Month extends AbstractMonth {

   JANUARY,
   FEBRUARY,
   MARCH
}
ทำไมสิ่งนี้ถึงเกิดขึ้น? เมื่อเราเขียนโปรแกรม:
public enum Month
คอมไพเลอร์แปลงคำสั่งนี้เป็นโค้ดดังนี้:
public Class Month extends Enum
ดังที่คุณทราบแล้วว่า Java ไม่อนุญาตให้มีการสืบทอดหลายรายการ ดังนั้นAbstractMonthเราจึงไม่สามารถสืบทอดจาก การออกแบบใหม่นี้สามารถEnumนำไปใช้ได้อย่างไร? และแตกต่างจากแบบเดิมที่มีstatic finalทุ่งนาอย่างไร? ตัวอย่างเช่นการออกแบบเก่าไม่อนุญาตให้เราใช้ชุดค่าของเราเองในswitch-expressions ลองนึกภาพว่าเราต้องการสร้างโปรแกรมที่จะเตือนเราว่ามีการเฉลิมฉลองวันหยุดอะไรบ้างในเดือนนี้:
public class HolidayReminder {

   public void printHolidays(Month month) {

       switch (month) {

           //error!
           case JANUARY:
       }
   }
}
อย่างที่คุณเห็น คอมไพเลอร์แสดงข้อผิดพลาด แต่หลังจาก Java 1.5 ปรากฏขึ้นenumทุกอย่างก็ง่ายขึ้นมาก:
public enum Month {

   JANUARY,
   FEBRUARY,
   MARCH
}

public class HolidayReminder {

   public void printHolidays(Month month) {

       switch (month) {

           case JANUARY:
               System.out.println("7 января будет Рождество!");
               break;
           case FEBRUARY:
               System.out.println("В феврале празднуется День Защитника Отечества - 23 февраля!");
               break;
           case MARCH:
               System.out.println("В марте отмечается Всемирный Женский День - 8 марта!");
               break;
       }
   }
}



public class Main {

   public static void main(String[] args) {

       HolidayReminder reminder = new HolidayReminder();
       reminder.printHolidays(Month.JANUARY);

   }

}
เอาต์พุตคอนโซล:

7 января будет Рождество!
โปรดทราบ: การเข้าถึงออบเจ็กต์Enumยังคงเป็นแบบคงที่เหมือนก่อน Java 1.5 เราไม่จำเป็นต้องสร้างวัตถุMonthเพื่อเข้าถึงเดือน เมื่อทำงานกับการแจงนับ สิ่งสำคัญมากคืออย่าลืมว่าEnumนี่คือชั้นเรียนที่เต็มเปี่ยม ซึ่งหมายความว่า หากจำเป็น คุณสามารถกำหนดตัวสร้างและวิธีการในนั้นได้ ตัวอย่างเช่น ในโค้ดก่อนหน้านี้ เราเพียงแค่ระบุค่า JANUARY, FEBRUARY, MARCH อย่างไรก็ตาม เราสามารถขยายขอบเขตของเราenum Monthได้ดังนี้:
public enum Month {

   JANUARY("Январь", 31),
   FEBRUARY("Февраль", 28),
   MARCH("Март", 31),
   APRIL("Апрель", 30),
   MAY("Май", 31),
   JUNE("Июнь", 30),
   JULY("Июль", 31),
   AUGUST("Август", 31),
   SEPTEMBER("Сентябрь", 30),
   OCTOBER("Октябрь", 31),
   NOVEMBER("Ноябрь", 30),
   DECEMBER("Декабрь", 31);

   private String name;
   private int daysCount;

   Month(String name, int daysCount) {
       this.name = name;
       this.daysCount = daysCount;
   }

   public static Month[] getWinterMonths() {

       return new Month[]{DECEMBER, JANUARY, FEBRUARY};
   }

   public static Month[] getSummerMonths() {

       return new Month[]{JUNE, JULY, AUGUST};
   }

   public String getName() {
       return name;
   }

   public void setName(String name) {
       this.name = name;
   }

   public int getDaysCount() {
       return daysCount;
   }

   public void setDaysCount(int daysCount) {
       this.daysCount = daysCount;
   }

   @Override
   public String toString() {
       return "Month{" +
               "name='" + name + '\'' +
               ", daysCount=" + daysCount +
               '}';
   }
}
ที่นี่เราได้เพิ่ม 2 ฟิลด์ลงในของเราenum- ชื่อของเดือนและจำนวนวัน, ตัวสร้างที่ใช้ฟิลด์เหล่านี้, getters-setters, เมธอดtoString()รวมถึงเมธอดคงที่ 2 วิธี อย่างที่คุณเห็น ไม่มีปัญหากับสิ่งนี้ ดังที่เราได้กล่าวไว้ก่อนหน้านี้enumนี่คือคลาสที่เต็มเปี่ยม:
import java.util.Arrays;

public class Main {

   public static void main(String[] args) {

       System.out.println(Arrays.toString(Month.getSummerMonths()));

   }

}
เอาต์พุตคอนโซล:

[Month{name='Июнь', daysCount=30}, Month{name='Июль', daysCount=31}, Month{name='Август', daysCount=31}]
สุดท้ายนี้ ฉันอยากจะแนะนำหนังสือเกี่ยวกับ Java ที่มีประโยชน์อย่างยิ่งเล่มหนึ่งให้คุณ นั่นคือ“ Effective Java” โดย Joshua Bloch เอนัม.  ตัวอย่างการปฏิบัติ  การเพิ่มตัวสร้างและวิธีการ - 3ผู้เขียนเป็นหนึ่งในผู้สร้าง Java ดังนั้นคุณสามารถไว้วางใจคำแนะนำของเขาเกี่ยวกับการใช้เครื่องมือภาษาที่ถูกต้องและมีความสามารถอย่างแน่นอน :) เกี่ยวกับการบรรยายของเรา ฉันขอแนะนำให้คุณให้ความสนใจเป็นพิเศษกับบทของหนังสือที่อุทิศให้กับenum. มีประสิทธิผลในการอ่าน! :)
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION