본문 바로가기
Java/공부 & 트러블 슈팅

제네릭을 통해 계산기 프로그램의 기능 확장

by 정구정구 2026. 6. 8.

기존 정수 계산기

    public String Calculate(int firstNum, int secondNum, char operSymbol) {

        int answer;

        // 더하기
        if (operSymbol == '+') {
            answer = firstNum + secondNum;
        }

        // 빼기
        else if (operSymbol == '-') {
            answer = firstNum - secondNum;
        }

        // 곱하기
        else if (operSymbol == '*') {
            answer = firstNum * secondNum;
        }

        // 나누기
        else if (operSymbol == '/') {
            if (secondNum == 0) {
                return "0으로 나눌 수 없습니다.";
            }
            answer = firstNum / secondNum;
        }

        // 유효하지 않은 사칙연산
        else {
            return "유효하지 않은 사칙연산 입니다.";
        }
        
        // 연산식과 결과 값 저장
        results.add(firstNum + " " + operSymbol + " " + secondNum + " = " + answer);

        return Integer.toString(answer);
    }

 

 간단하게 만들었던 정수 계산기이다. 여기에 제네릭을 사용해 실수까지 연산 할 수 있도록 기능을 확장 해보려 한다.

 

 

첫 번째 시도

 가장 먼저 떠오른 방법은 calculate 메서드의 매개 변수를 제네릭으로 받아서 처리하는 것 이었다.

public <T extends Number> String Calculate(T firstNum, T secondNum, char operSymbol) {

        // 더하기
        if (operSymbol == OperatorType.ADD.getChar()) {
            answer = firstNum + secondNum;
        }
        
        ...
        
}

 

위와 같이 코드를 짜면 타입 변수 T가 Number 타입으로 제한되기 때문에 연산도 될 줄 알았다.

 

바로 빨간줄이 그어진다!

 

이유를 찾아보니 T에 들어오는 타입이 숫자로 제한된더라도 타입이 다르므로 일반적인 +, - 같은 연산 기능을 지원하지 않는 것이다.

 

 

두 번째 시도

interface Calculable<T> {
    T add(T a, T b);
    T subtract(T a, T b);
    T multiply(T a, T b);
    T divide(T a, T b);
}
class IntegerCalculator implements Calculable<Integer> {

    @Override
    public Integer add(Integer a, Integer b) {
        return a + b;
    }

    @Override
    public Integer subtract(Integer a, Integer b) {
        return a - b;
    }

    @Override
    public Integer multiply(Integer a, Integer b) {
        return a * b;
    }

    @Override
    public Integer divide(Integer a, Integer b) {
        return a / b;
    }
}
public class GenericCalculator<T> {

    private final Calculable<T> calculator;

    public GenericCalculator(Calculable<T> calculator) {
        this.calculator = calculator;
    }

    public T add(T a, T b) {
        return calculator.add(a, b);
    }

    public T subtract(T a, T b) {
        return calculator.subtract(a, b);
    }

    public T multiply(T a, T b) {
        return calculator.multiply(a, b);
    }

    public T divide(T a, T b) {
        return calculator.divide(a, b);
    }
}

 

 첫 번째 시도 이후, 위와 같이 인터페이스를 이용해서 매개 변수 타입 별로 연산을 정의해주는 방법을 생각해봤다. (코드는 실제로 구현하지 않았기 때문에 AI에게 부탁한 코드이다.) 

GenericCalculator<Integer> calculator1 =
        new GenericCalculator<>(new IntegerCalculator());
        
GenericCalculator<Double> calculator2 =
        new GenericCalculator<>(new DoubleCalculator());

 

 하지만 이 방법은 결국 타입별로 인스턴스를 여러 개 만들어서 입력 받은 값에 따라 다른 인스턴스에 배정해줘야 하는데 이거보다 좋은 방법이 없을까 생각을 해보았다.

 

 

세 번째 시도

 더 좋은 방법에 대해서 고민을 하다가 든 생각은 "어차피 int 타입으로 매개 변수를 받아도  double로 처리하면 되겠다" 였다.

public <T extends Number> String Calculate(T firstNum, T secondNum, char operSymbol) {

        double answer;

        // 더하기
        if (operSymbol == OperatorType.ADD.getChar()) {
            answer = firstNum.doubleValue() + secondNum.doubleValue();
        }

        // 빼기
        else if (operSymbol == OperatorType.SUBTRACT.getChar()) {
            answer = firstNum.doubleValue() - secondNum.doubleValue();
        }

        // 곱하기
        else if (operSymbol == OperatorType.MULTIPLY.getChar()) {
            answer = firstNum.doubleValue() * secondNum.doubleValue();
        }

        // 나누기
        else if (operSymbol == OperatorType.DIVIDE.getChar()) {
            if (secondNum.doubleValue() == 0) {
                return "0으로 나눌 수 없습니다.";
            }
            answer = firstNum.doubleValue() / secondNum.doubleValue();
        }

        // 유효하지 않은 사칙연산
        else {
            return "유효하지 않은 사칙연산 입니다.";
        }

        resultStrings.add(firstNum + " " + operSymbol + " " + secondNum + " = " + answer);

        return Double.toString(answer);
    }

 

 결국 위와 같이, 매개 변수로 받은 Number 데이터를 double로 캐스팅해서 연산을 하는 방법으로 마무리 했다.

 

 

결과