[Java] 계산기

김세림·2024년 4월 29일

Java_코드공부

목록 보기
4/7
post-thumbnail

step 1,2,3,4 로 이루어진 계산기 만들기를 해보려고 한다.

step 1


우선 calculator 클래스와 메서드를 만든 뒤에 조건문으로 하나씩 추가하면 될 것 같다.

public class Calculator{
	public double calculate(String operator, int firstNumber, int secondNumber){
    	switch(operator){
        	case "+" :
            	return firstNumber + secondNumber;
            case "-" :
            	return firstNumber - secondNumber;
            case "*" : 
            	return firstNumber * secondNumber;
            case "/" :
            	return (double)firstNumber / secondNumber;
            default:
                return -1; 
                //만약 operator가 잘 못 들어온다면 -1을 반환해서 오류를 알림.
        }
    }
}

step 2


이건 아주 간단하다! case를 하나 더 써서 아래에 추가하면된다.

	case "%":
    	return firstNumber % secondNumber;

step 3


우선 더하기~나누기 클래스를 만드는게 우선인거 같고,
관계를 맺는 부분에선 생성자를 기본생성자가 아닌 저 클래스들을 매개변수로 하는 생성자를 만들어야할것 같다.
그리고나서 호출하는 부분도 만들어야겠다 생각된다!
이렇게하면 객체지향에 한걸음 다가설수 있게 되는 것 같다.

//AddOperation 클래스
public class AddOperation {
    public double operate(int firstNumber, int secondNumber){
        return firstNumber + secondNumber;
    }
}
//SubstractOperation 클래스
public class SubstractOperation {
    public double operate(int firstNumber, int secondNumber){
        return firstNumber - secondNumber;
    }
}
//MultiplyOperation 클래스
public class MultiplyOperation {
    public double operate(int firstNumber, int secondNumber){
        return firstNumber * secondNumber;
    }
}
//DivideOperation 클래스
public class DivideOperation {
    public double operate(int firstNumber, int secondNumber){
        return (double) firstNumber / secondNumber;
        // 나누기는 소수점이 나올 수 있으므로 double로 캐스팅하여
        // 강제형변환을 시켰다.
    }
}
//Calculator 클래스
public class Calculator{
    AddOperation addOperation;
    SubstractOperation substractOperation;
    MultiplyOperation multiplyOperation;
    DivideOperation divideOperation;

    public Calculator(AddOperation addOperation, SubstractOperation substractOperation, MultiplyOperation multiplyOperation, DivideOperation divideOperation){
        this.addOperation = addOperation;
        this.substractOperation = substractOperation;
        this.multiplyOperation = multiplyOperation;
        this.divideOperation = divideOperation;
    }
    public double calculate(String operator, int firstNumber, int secondNumber){
        switch(operator){
            case "+" :
                return addOperation.operate(firstNumber, secondNumber);
            case "-" :
                return substractOperation.operate(firstNumber, secondNumber);
            case "*" :
                return multiplyOperation.operate(firstNumber, secondNumber);
            case "/" :
                return divideOperation.operate(firstNumber, secondNumber);
            default:
                return -1;
        }
    }
}

step 4


step3을 하면서도 '어? 사칙연산하는 클래스에서 같은 메소드를 사용하네? 추상화하나?'라고 생각을 했는데 역시 다음 스텝은 추상화부분이었다.
우선 겹치는 operate를 한곳으로 몰아넣고 오버라이딩하면될것 같다.
그리고 calculator도 해당 추상클래스를 가지고오는 것으로 변경해야할것이다.
그런데 거기까지는 하겠는데 갑자기 calculate 메서드 매개변수에 operator가 사라졌다.. 이거에 대해서 '일단은 만들고 나서 main에서 테스트할때 operator별로 그냥 클래스를 호출하는건가?'라고 생각하며 일단 만들기 시작해보았다.

//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;
    }
}
//다른 클래스들도 AddOperation와 같은 방법으로 상속하고 override한것이기 때문에 
//하나만 작성한다.

//Calculator클래스
public class Calculator{
    private AbstractOperation abstractOperation;

    public Calculator(AbstractOperation abstractOperation){
        this.abstractOperation = abstractOperation;
    } //생성자를 abstract 추상클래스로 변경

    public void setAbstractOperation(AbstractOperation abstractOperation) {
        this.abstractOperation = abstractOperation;
    } // 다른 연산자를 사용하기 위해 setter를 사용해 클래스를 바꿔준다.

    public double calculate(int firstNumber, int secondNumber){
        return abstractOperation.operate(firstNumber, secondNumber); 
        //값두개만 매개변수로 가지게 변경!
    }
}

위처럼 변경한 다음 main을 이용해서 테스트를 해보았다.

public class Main {
    public static void main(String[] args) {
        Calculator calculator = new Calculator(new AddOperation());
        System.out.println(calculator.calculate(4,5));

        calculator = setOperation(new DivideOperation());
        System.out.println(calculator.calculate(5,2));
    }
}
//출력
//9
//2.5

문제없이 잘 작동되는 것을 확인하였고, 나는 계산기에 직접 값과 operator를 입력하여 나오게 하고싶어 main을 좀 더 수정하였다.

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("첫번째 숫자를 입력하세요.");
        int num1 = sc.nextInt();
        System.out.println("연산자를 입력하세요. (+, -, *, /)");
        String operator = sc.nextLine();
        System.out.println("두번째 숫자를 입력하세요.");
        int num2 = sc.nextInt();

        Calculator calculator = new Calculator(new AddOperation()); //초기값은 add로 설정
        switch (operator){
            case "+":
                calculator.setAbstractOperation(new AddOperation());
                break;
            case "-":
                calculator.setAbstractOperation(new SubstractOperation());
                break;
            case "*":
                calculator.setAbstractOperation(new MultiplyOperation());
                break;
            case "/":
                calculator.setAbstractOperation(new DivideOperation());
                break;
            default:
                System.out.println("연산자 입력 오류!");
        }
        if(operator.equals("+") ||operator.equals("-") ||operator.equals("*") ||operator.equals("/")){
            System.out.println("결과 : " + calculator.calculate(num1, num2));
        }
    }
}

이론상 문제없는 코드라고 생각했는데 입력부분에서 문제가 생겼다.
첫번째 숫자를 nextInt를 한 다음 연산자를 받아야하는데 그냥 뛰어넘고 두번째 숫자를 받으라고 하는 것이었다.

알고보니 이문제는 nextLine문제였는데 nextLine이라는 것 자체가 엔터를 치면 넘어가는 것인데 nextInt를 하고나서 엔터를 쳤으니 그 값이 남아있어서 nextLine을 바로 이어서 하게되면 해당 엔터값을 받아 공란으로 받는 문제였다.

이를 해결하기 위해 nextInt()다음에 nextLine을 하나 더 넣어서 해결하였다!

Scanner sc = new Scanner(System.in);
System.out.println("첫번째 숫자를 입력하세요.");
int num1 = sc.nextInt();
sc.nextLine();
System.out.println("연산자를 입력하세요. (+, -, *, /)");
String operator = sc.nextLine();
System.out.println("두번째 숫자를 입력하세요.");
int num2 = sc.nextInt();

다 완성 시킨 후 강사님의 코드와 리뷰를 보며 확인을 해보았을 때 대부분이 비슷했지만 한가지 생각했어야했던 점이 있었다.
Step 3의 calculator부분에서
클래스들을 위에서 선언할때 private final을 붙이는 부분이다.
add, substract, multiply, divide 네개가 각자가 하는 것에서 바뀌거나 하지않으므로 상수처리를 해주는 것이 더 좋을 것이라고 생각되었다.

0개의 댓글