JAVA 계산기 만들기

‍박태우·2024년 9월 3일

nbc_spring

목록 보기
8/28

Java 의 클래스를 이용하여 계산기를 만들어보자

문제 : https://online.spartacodingclub.kr/enrolleds/66d1723f7ca92f5c4ec80a87/ehomeworks/66d172407ca92f5c4ec80ace


step 1. Calculator 클래스 만들기

  • Calculator.class
public class Calculator {
    double calculate(String operator, int firstNumber, int secondNumber) {


        double result = 0.0; // double 형 변수 초기화
        try {
            switch (operator) {
                case "+":
                    result = firstNumber + secondNumber;
                    break;
                case "-":
                    result = firstNumber - secondNumber;
                    break;
                case "*":
                    result = firstNumber * secondNumber;
                    break;
                case "/":
                    if (secondNumber == 0) {
                        throw new ArithmeticException("Cannot divide by zero");
                    }
                    result = (double) firstNumber / secondNumber;
                    break;
                default:
                    System.out.println("Invalid operator");
                    break; // 선택사항
            }
        } catch (ArithmeticException e) {
            System.out.println("Cannot divide by zero");
        }

        return result;
    }


}

switch문을 이용하여 로직을 구현하였다.
result 변수를 double 형으로 초기화하였고 메서드의 매개변수로 받는 operator 를 경우에 따라 firstNumbersecondNumber를 연산하도록 하였다.

- 특이 사항 :

1) 0으로 나누면 오류나 예외가 발생하지 않고 infinite(무한) 값이 출력되어서 이 경우에는 예외를 던지게 하여 일부로 예외가 발생하도록 하였다.

2) default를 통해 올바르지 않은 연산자가 입력된 경우에는 'Invalid Operator' 가 출력되도록 하였다.

- 결과 테스트 :

public class Main {
    public static void main(String[] args) {
        
        // 테스트 코드
        Calculator calculator = new Calculator();

        double sum = calculator.calculate("+", 2,5);
        double div = calculator.calculate("/", 3,5);
        double divErr = calculator.calculate("/", 3,0);
        // 예외 발생 (처리함)
        double opErr = calculator.calculate("?", 3,0);
        // default 로 예외 문자 출력 처리


        System.out.println("---------");
        System.out.println("sum " + sum);
        System.out.println("div " + div);


    }
}

=> 정상적인 '+', '/' 의 경우는 올바르게 각 변수에 전달 되었지만
divErr , opErr 와 같은 경우는 이전의 Calculator 클래스에서 처리되도록 했기 때문에 먼저 결과가 나오는 모습이다. 이후 구분선을 기준으로 아래쪽에 정상적으로 처리된 sum , div 값이 나오는 것을 확인 할 수 있었다.

1단계 성공!! (아직은 어렵지는 않다...)

step 2. 나머지 연산자 기능 추가

case "%" :
      result = firstNumber % secondNumber;
      break;

=> 위와 같이 나머지 연산자 (%) 의 경우를 case 문에 추가하였다.
(테스트도 잘됨)

2단계 성공!! (이정도는 뭐...)

step 3. 클래스 간 관계 맺기

=> 간단하게 말하자면 기존에 swtich 문을 통해 만든 Calculator 클래스를 각 연산자별 class 로 만들어 보자는 의미이다.

-일단 각자의 클래스를 만들어 보았다.

  • AddOperation class
public class AddOperation {

    public double operate(int firstNumber, int secondNumber) {
        return firstNumber + secondNumber;
    }
}
  • SubstractOperation class
public class SubstractOperation {
    public double operate(int firstNumber, int secondNumber) {
        return firstNumber - secondNumber;
    }
}
  • MultiplyOperation class
public class MultiplyOperation {
    public double operate(int firstNumber, int secondNumber) {
        return firstNumber * secondNumber;
    }
}
  • DivideOperation class
public class DivideOperation {
    public double operate(int firstNumber, int secondNumber) {
        return (double)firstNumber / secondNumber;
    }
}

그림에서 주어진 것과 같이 operate 메서드를 각 클래스마다 선언 하였다.

  • 수정된 Calculator 클래스
public class Calculator {

    private AddOperation addOperation = new AddOperation();
    private SubstractOperation substractOperation = new SubstractOperation();
    private MultiplyOperation multiplyOperation = new MultiplyOperation();
    private DivideOperation divideOperation = new DivideOperation();


    double calculate(String operator, int firstNumber, int secondNumber) {



        double result = 0.0; // double 형 변수 초기화
        try {
            switch (operator) {
                case "+":
                    result = addOperation.operate(firstNumber, secondNumber);
                    break;
                case "-":
                    result = substractOperation.operate(firstNumber, secondNumber);
                    break;
                case "*":
                    result = multiplyOperation.operate(firstNumber, secondNumber);
                    break;
                case "/":
                    if (secondNumber == 0) {
                        throw new ArithmeticException("Cannot divide by zero");
                    }
                    result = divideOperation.operate(firstNumber, secondNumber);
                    break;
                case "%" :
                    result = firstNumber % secondNumber;
                    break;
                default:
                    System.out.println("Invalid operator");
                    break; // 선택사항
            }
        } catch (ArithmeticException e) {
            System.out.println("Cannot divide by zero");
        }

        return result;
    }


}

기존에는 일반 연산자 + - * / 를 이용하여 case 문을 작성했지만 위 경우에는 만달어진 class 를 이용하여 Calculator 에 포함 시키고 해당 클래스들을 포함시킴

public class Main {
    public static void main(String[] args) {
        
        // 테스트 코드
        Calculator calculator = new Calculator();

        int firstNumber = 7;
        int secondNumber = 3;

        double sum = calculator.calculate("+",firstNumber, secondNumber);
        double sub = calculator.calculate("-",firstNumber, secondNumber);
        double mul = calculator.calculate("*",firstNumber, secondNumber);
        double div = calculator.calculate("/",firstNumber, secondNumber);

        //double divErr = calculator.calculate("/", 3,0);
        // 예외 발생 (처리함)
        //double opErr = calculator.calculate("?", 3,0);
        // default 로 예외 문자 출력 처리

        double remain = calculator.calculate("%", 5,2);


        System.out.println("---------");
        System.out.println("sum " + sum);
        System.out.println("sub " + sub);
        System.out.println("mul " + mul);
        System.out.println("div " + div);

        System.out.println("remain " + remain);


    }
}

main 문을 이용하여 Calculator의 calculate 메서드를 이용하여 이전과 마찬가지로 결과를 출력해보았다.

3단계 성공!! (아마 많은 또 다른 방법도 있을 것이다.)

step 4. 추상클래스로 확장하기

=> AbstractOperation 클래스를 이용하여 추상메서드를 이용하고 그것을 각 Operation 클래스에서 오버라이딩 하여 활용하는 문제이다.

  • AbstractOperation 클래스
public abstract class AbstractOperation {
    public abstract double operate(int firstNumber, int secondNumber); 
    // 추상메서드 
}

=> 위 추상메서드를 아래의 각 클래스에서 상속받아 각자 기능에 맞게 오버라이딩 한다.

  • AddOperation 클래스
public class AddOperation extends AbstractOperation{

    @Override
    public double operate(int firstNumber, int secondNumber) {
        return firstNumber + secondNumber;
    }
}
  • SubstractOperation 클래스
public class SubstractOperation extends AbstractOperation{

    @Override
    public double operate(int firstNumber, int secondNumber) {
        return firstNumber - secondNumber;
    }
}
  • MultiplyOperation 클래스
public class MultiplyOperation extends AbstractOperation{

    @Override
    public double operate(int firstNumber, int secondNumber) {
        return firstNumber * secondNumber;
    }
}
  • DividetOperation 클래스
public class DivideOperation extends AbstractOperation{

    @Override
    public double operate(int firstNumber, int secondNumber) {
        return (double)firstNumber / secondNumber;
    }
}

=> 위와 같이 오버라이딩을 완료하였으면 Calculator 클래스에서는 AbstractOperation 클래스를 포함하여 아래와 같이 사용한다.

  • Calculator 클래스
public class Calculator {

    private AbstractOperation operation;

    public Calculator(AbstractOperation operation) { // 생성자
        this.operation = operation;
    }

    public void setCalculator(AbstractOperation operation){ // setter
        this.operation = operation;
    }


    double calculate(int firstNumber, int secondNumber) {
        return operation.operate(firstNumber, secondNumber);
    }


}

생성자를 통해 원하는 operator 클래스를 생성과 함께 선택할 수 있으며
setCalculator 메서드 (setter)를 이용하여 연산자를 바꾸고 싶을때 바꿀 수 있도록 하였다.

이후 calculate 메서드를 이용하여 operation 인스턴스의 종류에 따라 알맞은 연산결과를 리턴하도록 하였다.

  • main 에서의 사용
public class Main {
    public static void main(String[] args) {
        
       // 테스트 코드
        Calculator calculator = new Calculator(new AddOperation());

        double add = calculator.calculate(2,3);
        System.out.println(add); // 5.0

        calculator.setCalculator(new SubstractOperation());
        double sub = calculator.calculate(2,3);
        System.out.println(sub); // -1.0

        calculator.setCalculator(new MultiplyOperation());
        double mul = calculator.calculate(2,3); // 6.0
        System.out.println(mul);

        calculator.setCalculator(new DivideOperation());
        double div = calculator.calculate(3,2); // 1.5
        System.out.println(div);

    }
}

calculator 인스턴스를 생성하면서 해당하는 클래스를 매개변수로 넣거나 setter 를 이용하여 사용하고 싶은 클래스로 변경하여 두개의 int 형 정수를 받아 결과를 계산하도록 하였다.

4단계도 성공 (시간이 좀 걸렸다. 생각보다 복잡한 과정이라 강의 자료를 참고하면서 수행하였는데 그러다 보니 공부가 되었던 문제 였던 것 같다.)
profile
잘 부탁드립니다.

0개의 댓글