CodeGym /Java Blog /무작위의 /열거형 실용적인 예. 생성자 및 메서드 추가
John Squirrels
레벨 41
San Francisco

열거형 실용적인 예. 생성자 및 메서드 추가

무작위의 그룹에 게시되었습니다
안녕! 오늘 우리는 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, 필수 필드, getter/setter 및 toString(). 물론 추가해야 하는 경우가 equals()아니면hashCode()완전한 행복을 이루기 위해 :) 그러나 여기에 우리는 개념적 문제가 있습니다. 기억하시겠지만 OOP의 주요 이점 중 하나는 실제 세계에서 엔터티를 쉽게 모델링할 수 있다는 것입니다. 의자, 자동차, 행성 - 일상 생활의 이러한 모든 개념은 추상화의 도움으로 프로그램에서 쉽게 표현됩니다. 문제는 일부 실제 엔터티의 값 범위가 엄격하게 제한된다는 것입니다. 1년에 4계절만 있습니다. 한 옥타브에는 8개의 음만 있습니다. 달력에는 12개월만 있습니다. 그리고 Ocean's 11의 Danny Ocean은 친구가 11명에 불과합니다. 우리의Month클래스에는 모든 필수 필드가 있습니다. 그러나 다른 프로그래머가 그것을 사용한다면 아무도 그 사람이 완전히 정신 나간 객체를 만드는 것을 막을 수 없습니다.

public class Main {

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

}
이것이 우리 코드에 나타나면 범인을 찾기가 쉽지 않을 것입니다! 한편으로, 객체를 생성하는 프로그래머는 클래스 Month가 "1년 중 한 달"을 의미한다는 것을 깨닫고 그런 넌센스를 쓰지 않을 수 있습니다. 반면에 프로그래머는 클래스 디자이너가 제공한 기능만 활용하고 있습니다. 임의의 이름과 날짜를 지정할 수 있습니까? 그것이 바로 우리가 얻은 것입니다. 그렇다면 이런 상황에서 우리는 어떻게 해야 할까요? 솔직히 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("January", 31);
   public static Month FEBRUARY = new Month("February", 28);
   public static Month MARCH = new Month("March", 31);

   @Override
   public String toString() {
       return "Month{" +
               "name='" + name + '\'' +
               ", daysCount=" + daysCount +
               '}';
   }
}
여기서는 예제를 더 짧게 만들기 위해 개월 수를 12개월에서 3개월로 줄였습니다. 이러한 디자인으로 문제를 해결할 수 있습니다. 개체를 만드는 기능은 개인 생성자로 제한되었습니다.

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 개발자들은 기존 문제에 주목했습니다. 물론 프로그래머가 언어에서 사용할 수 있는 도구를 사용하여 솔루션을 제시할 수 있었던 것은 훌륭하지만 쉽지는 않습니다! 초심자에게도 분명한 해결책이 필요했습니다. 그래서 EnumJava에 나타났습니다. 기본적으로 Enum제한된 개체 값 집합을 제공하는 Java 클래스입니다. 다음과 같이 표시됩니다.

public enum Month {
  
   JANUARY,
   FEBRUARY,
   MARCH
}
정의에서 EnumJava 클래스라고 표시했지만 정말 사실입니까? 예, 확인할 수도 있습니다. Month예를 들어 열거형이 다른 클래스를 상속 하도록 해보세요 .

public abstract class AbstractMonth {
}

// Error! The extends clause cannot be used with an enum
public enum Month extends AbstractMonth {

   JANUARY,
   FEBRUARY,
   MARCH
}
왜 그런 일이 발생합니까? 우리가 쓸 때:

public enum Month
컴파일러는 이 명령문을 다음 코드로 변환합니다.

public Class Month extends Enum
이미 알고 있듯이 Java는 다중 상속을 지원하지 않습니다. 따라서 상속할 수 없습니다 AbstractMonth. 이 새로운 구조를 어떻게 Enum사용할 수 있습니까? 필드 가 있는 이전 구성과 어떻게 다른가요 static final? 예를 들어, 이전 구문에서는 switch명령문에서 자체 값 집합을 사용할 수 없었습니다. 매달 축하하는 휴일을 상기시키는 프로그램을 만들고 싶다고 상상해 보십시오.

public class HolidayReminder {

   public void printHolidays(Month month) {

       switch (month) {

           // Error!
           case JANUARY:
       }
   }
}
보시다시피 컴파일러는 여기에서 오류를 발생시킵니다. 그러나 enumJava 1.5에 등장하자 모든 것이 훨씬 간단해졌습니다.

public enum Month {

   JANUARY,
   FEBRUARY,
   MARCH
}

public class HolidayReminder {

   public void printHolidays(Month month) {

       switch (month) {
          
           case JANUARY:
               System.out.println("New Year's Day is January 1st!");
               break;
           case FEBRUARY:
               System.out.println("Valentine's Day is February 14th!");
               break;
           case MARCH:
               System.out.println("Saint Patrick's Day is March 17th!");
               break;
       }
   }
}


public class Main {

   public static void main(String[] args) {

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

   }

}
콘솔 출력:

New Year's Day is January 1st!
객체 에 대한 액세스는 EnumJava 1.5 이전과 마찬가지로 정적으로 유지되었습니다. Month월에 액세스하기 위해 개체를 만들 필요가 없습니다 . Enum열거형으로 작업할 때 본격적인 클래스임을 잊지 않는 것이 매우 중요합니다 . 즉, 필요한 경우 생성자와 메서드를 정의할 수 있습니다. 예를 들어, 이전 코드 조각에서는 JANUARY, FEBRUARY, MARCH 값을 지정했습니다. 그러나 Month다음과 같이 열거형을 확장할 수 있습니다.

public enum Month {

   JANUARY("January", 31),
   FEBRUARY("February", 28),
   MARCH("March", 31),
   APRIL("April", 30),
   MAY("May", 31),
   JUNE("June", 30),
   JULY("July", 31),
   AUGUST("August", 31),
   SEPTEMBER("September", 30),
   OCTOBER("October", 31),
   NOVEMBER("November", 30),
   DECEMBER("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 +
               '}';
   }
}
여기에서 우리는 enum2개의 필드(월 이름 및 일 수), 이러한 필드를 사용하는 생성자, getter/setter, 메서드 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='June', daysCount=30}, Month{name='July', daysCount=31}, Month{name='August', daysCount=31}]
마지막으로 Joshua Bloch의 "Effective Java" 라는 매우 유용한 Java 책을 추천하고 싶습니다 . 열거형  실용적인 예.  생성자 및 메서드 추가 - 3저자는 Java의 제작자 중 한 명이므로 언어 ​​도구를 정확하고 유능하게 사용하는 방법에 대한 그의 조언을 확실히 신뢰할 수 있습니다. :) 강의와 관련하여 Enum. 즐거운 독서! :)
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION