Generics의 사용
Generics를 사용해서 기존엔 int였던 피연산자 타입을 double로도 받아올 수 있도록 하는 것이 Lv.3의 요구사항 중 하나였다.
내가 구현한 내용은 다음과 같다.
public class ArithmeticCalculator<T extends Number> {
private final List<Double> result = new LinkedList<>();
public Double calculate(T firstNum, T secondNum, String operator) {
double result = OperatorType.fromSymbol(operator).operate(firstNum,secondNum);
setResult(result);
return result;
}
... 기타 메서드
}
그런데, ArithemeticCalculator를 제네릭 클래스로 변경하지 않아도 다형성을 이용하여 다음과 같이 변경하면 동일하게 동작한다.
public class ArithmeticCalculator {
private final List<Double> result = new LinkedList<>();
public Double calculate(Number firstNum, Number secondNum, String operator) {
double result = OperatorType.fromSymbol(operator).operate(firstNum,secondNum);
setResult(result);
return result;
}
... 기타 메서드
}
매개변수로 Number 타입을 지정해서 계산이 가능하다. 그렇다면 굳이 계산기 클래스를 제네릭 클래스로 만들 필요가 있는건가? 라는 질문이 떠올랐다. 다형성을 이용하여 추상화된 타입으로 받는 것과 대비되는 이점은 뭐지??
calculate 메서드의 피연산자 타입을 특정 타입으로 일치시켜야 할 때
`정수 + 정수`, `실수 + 실수`, `정수 + 실수` 등 두 피연산자의 타입을 특정 타입으로 일치시켜야 하는 경우가 생기면 Generics의 이점을 활용할 수 있겠다.
ArithmeticCalculator<Integer> calculator = new ArithmeticCalculator<>();
calculator.calculate(1,1,"+");
calculator.calculate(1,1.4,"+"); // 에러 발생
다음과 같이 사용하면 피연산자로 정수만 받아야 한다.
과제 요구사항에는 '피연산자를 여러 타입으로 받을 수 있도록' 하라고 명세되어 있다.
요구사항을 읽고 `정수 + 실수`의 경우도 계산할 수 있어야 한다고 생각했고, 타입 매개변수로 `Number`를 대입한 계산기 인스턴스를 생성하여 사용하였다. 그치만 이는 제네릭 클래스로 만든 이유를 전혀 활용하지 않는 사용이라는 생각이 들어서 뭔가 혼란스러웠다 🫨
지금 당장은 사용하지 않더라도 피연산자의 타입을 일치시켜야 하는 경우를 고려할 수 있다는 점에서 의미가 있는건가 ?! 아님 내가 잘못 사용하고 있는건가?
멤버변수/메서드 반환 타입을 일치시켜야 할 때
1. Double로 매개변수가 들어오면 Double로 반환하고, Integer로 매개변수가 들어오면 Integer로 반환해야 할 때 제네릭을 활용할 수 있겠다.
2. 혹은 멤버변수인 results의 List 타입을 동적으로 설정해서 고정하고 싶을 때?
public class ArithmeticCalculator<T extends Number> {
private final List<T> results = new LinkedList<>();
public T calculate(T firstNum, T secondNum, String operator) {
T result;
// result = firstNum과 secondNum 계산 결과
return result;
}
... 기타 메서드
}
이 경우 제네릭을 사용하지 않고 Number로 단순히 추상화하여 매개변수를 가져온 후 Number로 반환하면 Integer와 Double 매개변수로 받고 전달할 수 있기는 하지만 사용하는 입장에서 형변환을 시켜줘야 하기 때문이다.
그치만 현재 진행 중인 계산기 과제에서는 정수끼리 나눗셈 연산을 했을 때 실수를 반환해야 하는 경우가 있기 때문에 결과 값이 실수가 될 수 있어야 한다. (5 / 2를 하면 계산 결과가 2.5가 될 것을 기대하므로)
1. 따라서 calculate 메서드의 반환타입을 Double로 고정했고,
2. 멤버변수 `results`의 List 타입 역시 Double로 고정했는데 ... 이 부분이 잘못된건가?
결론
- 현재 요구사항에서 내가 잘못 이해한 부분이 있는걸까? 🥲
- 지금 클래스에서 제네릭의 이점을 활용할 수 있는 방안을 생각해보았지만 떠올리기가 어려웠다. 내가 생각 못 한 다른 방안이 있을까??
'TIL' 카테고리의 다른 글
계산기 과제 : 계산 결과 Lambda&Stream 필터링 조회 구현하기 (0) | 2025.01.07 |
---|---|
계산기 과제 : Java Generics, Enum 활용기 (0) | 2025.01.06 |
날아갈랑말랑했던 SQL 문법 복기 (2) (1) | 2024.12.27 |
날아갈랑말랑했던 SQL 기본 문법 복기 (1) (0) | 2024.12.26 |