
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를 경우에 따라firstNumber와secondNumber를 연산하도록 하였다.
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 값이 나오는 것을 확인 할 수 있었다.

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

=> 간단하게 말하자면 기존에 swtich 문을 통해 만든 Calculator 클래스를 각 연산자별 class 로 만들어 보자는 의미이다.
public class AddOperation {
public double operate(int firstNumber, int secondNumber) {
return firstNumber + secondNumber;
}
}
public class SubstractOperation {
public double operate(int firstNumber, int secondNumber) {
return firstNumber - secondNumber;
}
}
public class MultiplyOperation {
public double operate(int firstNumber, int secondNumber) {
return firstNumber * secondNumber;
}
}
public class DivideOperation {
public double operate(int firstNumber, int secondNumber) {
return (double)firstNumber / secondNumber;
}
}
그림에서 주어진 것과 같이
operate메서드를 각 클래스마다 선언 하였다.
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 메서드를 이용하여 이전과 마찬가지로 결과를 출력해보았다.


=> AbstractOperation 클래스를 이용하여 추상메서드를 이용하고 그것을 각 Operation 클래스에서 오버라이딩 하여 활용하는 문제이다.
public abstract class AbstractOperation {
public abstract double operate(int firstNumber, int secondNumber);
// 추상메서드
}
=> 위 추상메서드를 아래의 각 클래스에서 상속받아 각자 기능에 맞게 오버라이딩 한다.
public class AddOperation extends AbstractOperation{
@Override
public double operate(int firstNumber, int secondNumber) {
return firstNumber + secondNumber;
}
}
public class SubstractOperation extends AbstractOperation{
@Override
public double operate(int firstNumber, int secondNumber) {
return firstNumber - secondNumber;
}
}
public class MultiplyOperation extends AbstractOperation{
@Override
public double operate(int firstNumber, int secondNumber) {
return firstNumber * secondNumber;
}
}
public class DivideOperation extends AbstractOperation{
@Override
public double operate(int firstNumber, int secondNumber) {
return (double)firstNumber / secondNumber;
}
}
=> 위와 같이 오버라이딩을 완료하였으면 Calculator 클래스에서는 AbstractOperation 클래스를 포함하여 아래와 같이 사용한다.
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인스턴스의 종류에 따라 알맞은 연산결과를 리턴하도록 하였다.
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 형 정수를 받아 결과를 계산하도록 하였다.