-
[Java] 열거형 (Enum)IT Study/컴퓨터 기초 2023. 4. 6. 15:21728x90

1. 열거형이란?
열거형은 서로 연관된 상수들의 집합을 나타내는 것으로,
여러 개의 상수 중 하나를 선택해야 하는 경우 유용하게 사용할 수 있습니다.
우리는 열거형을 통해 상수의 이름만으로 해당 상수가 어떤 값을 나타내는지 확인할 수 있기 때문에 가독성이 높아집니다.
2. 열거형의 선언
2-1. 간단한 열거형 선언
enum 키워드를 사용하여, 상수를 쉼표로 구분하여 선언합니다. (열거형 상수는 대문자로 작성하는 것을 권장합니다.)
enum 열거형명 { 상수명1, 상수명2, 상수명3... }enum Weekday { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY }public class Main { public static void main(String[] args) { Weekday today = Weekday.MONDAY; if(today == Weekday.MONDAY) { System.out.println("오늘은 월요일입니다."); } } }정의된 상수를 사용하기 위해서는 열거형명.상수명으로 사용할 수 있습니다.
더하여, 열거형 상수는 독립적인 객체이므로 비교할 때에는 == 연산자를 사용합니다.
2-2. 열거형 생성자와 멤버 변수
열거형 내에서는 각 상수에 값을 할당하고, 생성자와 멤버 변수를 추가할 수 있습니다.
열거형에서 상수에 멤버 변수를 넣어주고 싶을 때는 아래와 같은 순서로 진행합니다.
1. 상수 선언
2. 상수가 가질 멤버 변수 확인
3. 상수가 가질 멤버 변수의 개수만큼 private final으로 멤버 변수 선언 (게터 호출)
4. 기본 생성자 선언 및 멤버 변수 초기화
5. 상수에 멤버 변수 값 할당1. 상수 선언
2. 상수가 가질 멤버 변수 확인
enum Animal { CAT, DOG, BIRD; // CAT("고양이", 4) // 멤버 변수 : 이름, 다리 수 }3. 상수가 가질 멤버 변수의 개수만큼 private final으로 멤버 변수 선언 (게터 호출)
enum Animal { CAT, DOG, BIRD; // 멤버 변수 선언 private final String name; private final int legs; // 게터 호출 public String getName() { return name; } public int getLegs() { return legs; } }4. 기본 생성자 선언 및 멤버 변수 초기화
enum Animal { CAT, DOG, BIRD; private final String name; private final int legs; public String getName() { return name; } public int getLegs() { return legs; } // 생성자 선언 및 멤버 변수 초기화 Animal(String name, int legs) { this.name = name; this.legs = legs; } }5. 상수에 멤버 변수 값 할당
enum Animal { // 상수에 멤버 변수 값 할당 CAT("고양이", 4), DOG("개", 4), BIRD("새", 2); private final String name; private final int legs; Animal(String name, int legs) { this.name = name; this.legs = legs; } public String getName() { return name; } public int getLegs() { return legs; } }2-3. 추상 메서드와 상수별 메서드 구현
열거형은 추상 메서드를 가질 수 있습니다.
이전에 배운 추상 메서드는 자식 클래스에서 상속하여 구현해야 했지만,
열거형에서의 추상 메서드는 열거형 안에서 선언과 구현을 해야 합니다.
🔍 특히 열거형에서의 추상 메서드는 열거형 상수별로 모두 구현해야 한다는 것이 중요한 포인트입니다.
1. 상수 선언
2. 상수가 가질 멤버 변수 확인
3. 상수가 가질 멤버 변수의 개수만큼 private final으로 멤버 변수 선언 (게터 호출)
4. 기본 생성자 선언 및 멤버 변수 초기화
5. 상수에 멤버 변수 값 할당
6. 추상 메서드 선언
7. 상수별로 추상 메서드 구현1. 상수 선언
2. 상수가 가질 멤버 변수 확인
public enum Calculator { PLUS, MINUS, MULTIPLY, DIVIDE; // PLUS("+") // 멤버 변수 : 연산자 기호 }3. 상수가 가질 멤버 변수의 개수만큼 private final으로 멤버 변수 선언 (게터 호출)
public enum Calculator { PLUS, MINUS, MULTIPLY, DIVIDE; // 멤버 변수 선언 private String operator; // 게터 호출 public String getOperator() { return operator; } }4. 기본 생성자 선언 및 멤버 변수 초기화
public enum Calculator { PLUS, MINUS, MULTIPLY, DIVIDE; private String operator; public String getOperator() { return operator; } // 생성자 선언 및 멤버 변수 초기화 Calculator(String operator) { this.operator = operator; } }5. 상수에 멤버 변수 값 할당
public enum Calculator { // 상수에 멤버 변수 값 할당 PLUS("+"), MINUS("-"), MULTIPLY("*"), DIVIDE("/"); private String operator; public String getOperator() { return operator; } Calculator(String operator) { this.operator = operator; } }6. 추상 메서드 선언
public enum Calculator { PLUS("+"), MINUS("-"), MULTIPLY("*"), DIVIDE("/"); private String operator; public String getOperator() { return operator; } Calculator(String operator) { this.operator = operator; } // 추상 메서드 선언 public abstract int calculate(int n, int m); }7. 상수별로 추상 메서드 구현
public enum Calculator { // 상수 별 추상 메서드 구현 PLUS("+") { @Override public int calculate(int n, int m) { return n + m; } }, MINUS("-") { public int calculate(int n, int m) { return n - m; } }, MULTIPLY("*") { public int calculate(int n, int m) { return n * m; } }, DIVIDE("/") { public int calculate(int n, int m) { if(m == 0) { throw new ArithmeticException("분모 0 불가"); } else { return n / m; } } }; private String operator; public String getOperator() { return operator; } Calculator(String operator) { this.operator = operator; } public abstract int calculate(int n, int m); }열거형을 만들 때에는 순서에 따라 만든다고 생각하면 훨씬 쉬워집니다.
(열거형을 어렵게 생각하지 않고 활용하는 것을 연습해야겠습니다😊)
3. 열거형의 예시
3-1. 요일(Day or Week) 열거형
열거형은 switch문에서 매우 유용하게 사용할 수 있습니다.
아래 요일 열거형의 예시를 보며 switch문에서 활용하는 방법을 익혀봅시다.
public enum Day { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY }public class Main { public static void main(String[] args) { Day day = Day.MONDAY; switch(day) { case MONDAY: System.out.println("월요일입니다."); break; case TUESDAY: System.out.println("화요일입니다."); break; case WEDNESDAY: System.out.println("수요일입니다."); break; case THURSDAY: System.out.println("목요일입니다."); break; case FRIDAY: System.out.println("금요일입니다."); break; case SATURDAY: System.out.println("토요일입니다."); break; case SUNDAY: System.out.println("일요일입니다."); break; } } }위 코드에서는 switch문의 매개변수로 Day 타입의 변수 day를 사용하며, case문에서는 열거형 Day의 상수를 사용합니다.
3-2. 계절(Season) 열거형
각 계절에 대한 한글 이름과 영어 이름을 멤버 변수로 갖도록 열거형을 구현하며,
생성자를 구현하고 멤버 변수에 저장하는 방법에 대해 확인해 보겠습니다.
public enum Season { SPRING("봄", "Spring"), SUMMER("여름", "Summer"), FALL("가을", "Fall"), WINTER("겨울", "Winter"); private String koreanName; private String englishName; Season(String koreanName, String englishName) { this.koreanName = koreanName; this.englishName = englishName; } public String getKoreanName() { return koreanName; } public String getEnglishName() { return englishName; } }위 열거형의 상수는 Season 열거형의 인스턴스로, 열거형의 이름과 함께 한국어와 영어 이름을 가지고 있습니다.
열거형 속 멤버 변수는 외부에서 직접 수정할 필요가 없기 때문에 해당 변수를 private으로 설정하며,
외부에서 멤버 변수에 접근하기 위해서는 게터 메서드인 getKoreanName(), getEnglishName()를 사용해야 합니다.
public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.print("계절 입력 > ");String input = sc.nextLine(); Season season = getSeason(input); if(season == null) { System.out.println("잘못된 입력입니다."); return; } String activity = getActivityBySeason(season); System.out.println("오늘 추천하는 활동은 " + activity + "입니다."); } public static Season getSeason(String input) { Season[] seasons = Season.values(); for (Season season : seasons) { if (season.getKoreanName().equalsIgnoreCase(input) || season.getEnglishName().equalsIgnoreCase(input)) { return season; } } return null; } public static String getActivityBySeason(Season season) { switch(season) { case SPRING : return "산책"; case SUMMER : return "수영"; case FALL : return "하이킹"; case WINTER : return "스키"; default : throw new AssertionError("Unknown season: " + season); } } }getSeason 메서드는 사용자로부터 입력을 받아 해당하는 계절을 Season 열거형의 상수로 반환하는 역할을 합니다.
입력된 문자열이 열거형 상수의 한국어 이름이나 영어 이름과 일치하면 해당 상수를 반환하고, 그렇지 않으면 null을 반환합니다.
main 메서드에서는 사용자로부터 계절을 입력받고, getSeason 메서드를 호출하여 입력된 문자열에 해당하는 계절을 구합니다.
만약 getSeason 메서드가 null을 반환하면, "잘못된 입력입니다." 메시지를 출력하고 프로그램을 종료합니다.
그렇지 않으면 getActivityBySeason 메서드를 호출하여 해당 계절에 추천하는 활동을 출력하도록 작성했습니다.
3-3. 사칙연산(Operation or Calculator) 열거형
public enum Calculator { PLUS("+") { public int calculate(int n, int m) { return n + m; } }, MINUS("-") { public int calculate(int n, int m) { return n - m; } }, MULTIPLY("*") { public int calculate(int n, int m) { return n * m; } }, DIVIDE("/") { public int calculate(int n, int m) { if(m == 0) { throw new ArithmeticException("분모 0 불가"); } else { return n / m; } } }; private String operator; public String getOperator() { return operator; } Calculator(String operator) { this.operator = operator; } public abstract int calculate(int n, int m); }import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.print("첫 번째 정수 입력 > "); int n = sc.nextInt(); System.out.print("두 번째 정수 입력 > "); int m = sc.nextInt(); System.out.print("연산자 입력 (+, -, *, /) > "); String operator = sc.next(); Calculator calculator = getCalculator(operator); if(calculator == null) { System.out.println("잘못된 연산자입니다."); return; } int result = calculator.calculate(n, m); System.out.printf("%d %s %d = %d\n", n, calculator.getOperator(), m, result); } public static Calculator getCalculator(String operator) { Calculator[] calculators = Calculator.values(); for (Calculator calculator : calculators) { if (calculator.getOperator().equals(operator)) { return calculator; } } return null; } }위의 코드에서 getCalculator 메서드는 입력받은 연산자를
Calculator 열거형의 상수와 비교하여 일치하는 것을 찾아 반환합니다. 만약 일치하는 것이 없다면 null을 반환합니다.
이후 입력받은 연산자에 맞는 Calculator 상수를 찾아, 해당 상수의 calculate 메서드를 호출하여 사칙연산을 수행합니다.
마무리
이 글을 작성하기 전에는 열거형(Enum)이라는 단어만으로 코드 작성을 시작하기 힘들었습니다.
열거형도 마찬가지로 여러 예시를 보며, 사용하는 방식에 대해 이해하게 되었습니다.
궁금한 점이 생기신다면 댓글 남겨주세요.. ❤️
'IT Study > 컴퓨터 기초' 카테고리의 다른 글
[Java] 게터/세터(Getter/Setter)를 사용하는 이유 (2) 2023.04.10 [Java] 스레드 (Thread) (0) 2023.04.08 [Java] 제네릭과 와일드카드 (0) 2023.04.05 [Java] 컬렉션 프레임워크 4 (Map, HashMap 중심으로) (0) 2023.03.29 [Java] 컬렉션 프레임워크 3 (List, ArrayList 중심으로) (2) 2023.03.28