enum은 클래스다. 클래스정의와 완전 동일하다.
public enum OperatorType{
ADD('+'), ...
}
내부에 필드, 생성자, 메서드 다 넣을 수 있다? => enum클래스
enum은 상수들의 모음+부가정보를 담기위한 특수 클래스라고 생각하면 이해하기 쉽다.
public enum OperatorType{
ADD('+'),
SUBTRACT('-'),
MULTYPLY('*'),
DIVIDE('/'),
MOD('%');
private final char symbol;
// 각 연산자 타입이 가질 기호를 저장할 필드
OperatorType(char symbol){
//생성자임. enum상수가 만들어질 때마다 기호를 저장해주는 역할
this.symbol=symbol;
}
public char getSymbol(){
//원래 getter는 파라미터 안받음: 읽기 전용이기 때문.
// 외부에서 기호를 읽어올 수 있도록 getter제공
return symbol;
}
public static OperatorType fromChar(char ch){
// static: 객체 만들지 않고 클래스 이름으로 바로 호출 가능
// 왜 static으로 했는가?: 외부에서 + 같은 값을 던졌을 때,
// 바로 enm상수를 찾아주는 문 입구같은 메서드.
// OperatorType: enum값 중 하나를 리턴할 거임
// ch: 입력받은 연산 문제
// fromChar=메서드명
for(OperatorType op: OperatorType.values()){
//OperatorType.values()는 [ADD, SUBTRACT, MULTYPLY, DIVIDE, MOD]
// op는 순서대로 ADD, SUBTRACT, MULTYPLY, DIVIDE, MOD 반복
if(op.symbol==ch) return op;
// 입력한 문자와 ch 같다면 return
}
throw new ArithmeticException("지원하지 않는 연산자");
//반복문 다 돌았는데도 일치하는 symbol이 없으면 에러 던짐
}
}
위 코드 안에 주석으로 설명 달아놓긴 했는데 와닿지가 않아서 구조를 분해해 보며 이해해 보기로 했다.
public enum OperatorType
public enum OperatorType {
ADD, SUBTRACT, MULTIPLY, DIVIDE, MOD
}
+, - 같은 기호값이 없음, 단지 이름만 있고 실제 연산 기호는 if/switch 에서 따로 비교해야 한다.
쓰는 쪽에서 쓸데없이 연산자 기호와 enum을 따로 관리해야 해서 불편하기까지 한다.
그래서 기호에 따라 아래와 같이 switch문을 이용하여 해결해주면 된긴한데..
char giho = '+';
OperatorType opType;
switch (giho) {
case '+': opType = OperatorType.ADD; break;
case '-': opType = OperatorType.SUBTRACT; break;
// ... 직접 다 써야 함
}
이렇게 만들게 되면 번거롭고 직관적으로 예쁘지도 않기 때문에 enum을 활용해주면 아주 예쁜 모양이 나온다.
char giho = '+';
OperatorType opType = OperatorType.fromChar(giho);
아래코드와 같이 완성된 모습을 볼 수 있다.
public static OperatorType fromChar(char ch) {
for (OperatorType op : OperatorType.values()) {
if (op.getGiho() == ch) {
return op;
}
}
throw new ArithmeticException("지원하지 않는 연산자: " + ch);
}
즉, 위 코드와 아래 코드와 같은 기능을 한다.
'+' → OperatorType.ADD
'-' → OperatorType.SUBTRACT
... 이런 "변환 작업"이 필요함!
enum 활용하면서 fromChar을 만들어야겠다까지 생각을 못 했다.
그래서 enum사용 시 팁을 적어보자면 아래와 같다
num을 만들고,
enum이 외부 입력(char, String, int)을 받아서
자기 자신(enum 상수)을 "찾아주는" 역할이 필요하면
무조건 fromXxx() 메서드 만든다고 기억하자!
OperatorType.values()
for (OperatorType op : OperatorType.values()) { ... }
enum 클래스가 자동으로 만들어주는 메서드인데, ADD, SUBTRACT,...이런 모든 enum상수들을 배열로 반환해준다.
OperatorType.values()
// → [ADD, SUBTRACT, MULTIPLY, DIVIDE, MOD]
private final char symbol;
private final char symbol;
enum은 불변하기 때문에 final.
getter는 왜 있고, setter는 왜 없냐?
enum은 상수이기 때문에 절대 바뀌면 안된다. setter가 필요없다.
getter만 있으면 되는데 외부에서 giho를 읽기 전용으로 제공해준다.
따라서 enum은 setter사용 금지, getter사용 필수.