본 캠프_11일차

졸용·2025년 3월 3일

TIL

목록 보기
12/144

⭐ Lv2. 클래스를 적용해 기본적인 연산을 수행할 수 있는 계산기 만들기

첫 개인 프로젝트라 문법 이해와 학습을 위해 코드마다 메모처럼 주석처리를 했다. 나중에 익숙해진 문법들부터 차차 주석 제거 예정이다.

요구사항 체크리스트 ⬜✅ :

  • 사칙연산을 수행 후, 결과값 반환 메서드 구현 & 연산 결과를 저장하는 컬렉션 타입 필드를 사진 Calculator 클래스를 생성

    ✅ 사칙연산을 수행한 후, 결과값을 반환하는 메서드 구현

    ✅ 연산 결과를 저장하는 컬렉션 타입 필드를 가진 Calculator 클래스를 생성

    ✅ 1) 양의 정수 2개(0 포함)와 연산 기호를 매개변수로 받아 사칙연산(➕,➖,✖️,➗) 기늘을 수행한 후,
    2) 결과 값을 반환하는 메서드와 연산 결과를 저장하는 컬렉션 타입 필드를 가진 Calculator 클래스를 생성

package firstproject;

import java.util.ArrayList;
import java.util.List;

public class Calculator {

    // 연산 결과를 저장하는 컬렉션 필드
    public List<Integer> results;

    // 생성자
    public Calculator() {
        results = new ArrayList<>();  // 연산 결과를 저장할 ArrayList 초기화
    }

    // 사칙연산 수행
    public int performCalculation(int num1, int num2, char operator) {
        int result;
        switch (operator) {
            case '+':
                result = num1 + num2;
                break;
            case '-':
                result = num1 - num2;
                break;
            case '*':
                result = num1 * num2;
                break;
            case '/':
                if (num2 != 0) {
                    result = num1 / num2;
                } else {
                    System.out.println("0으로 나눌 수 없습니다.");
                    return Integer.MIN_VALUE; // 에러 표시
                }
                break;
            default:
                System.out.println("잘못된 연산자입니다.");
                return Integer.MIN_VALUE; // 에러 표시
        }

        // 결과를 리스트에 저장
        results.add(result);
        return result;
    }
}

  • Lv1에서 구현한 App 클래스의 main 메서드에 Calculator 클래스가 활용될 수 있도록 수정

    ✅ 연산 수행 역할은 Calculator 클래스가 담당

    ✅ 연산 결과는 Calculator 클래스의 연산 결과를 저장하는 필드에 저장

    ✅ 소스 코드 수정 후에도 수정 전의 기능들이 반드시 똑같이 동작해야 한다

package firstproject;

import java.util.Scanner;

public class App {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        Calculator calculator = new Calculator();

        while (true) {   // "exit"를 입력하기 전까지 계속 반복

            // 첫 번째 숫자 입력받기
            int num1 = getValidNumber(scanner, "첫 번째 숫자를 입력하세요: ");

            // 사칙연산 입력받기
            char operator = getValidOperator(scanner);

            // 두 번째 숫자 입력받기
            int num2 = getValidNumber(scanner, "두 번째 숫자를 입력하세요: ");

            // 사칙연산 수행 후 결과 출력
            int result = calculator.performCalculation(num1, num2, operator);
            // Calculator 클래스의 performCalculation 호출

            if (result != Integer.MIN_VALUE) {
                System.out.println("계산 결과: " + result);
            }

            // 계속 계산할지 물어보기
            if (!getContinueInput(scanner)) {
                System.out.println("계산기를 종료합니다.");
                return;
            }
        }
    }

    // 숫자 입력받기 (유효성 검사 포함)
    private static int getValidNumber(Scanner scanner, String prompt) {
        int num;
        while (true) {
            System.out.println(prompt);
            String input = scanner.nextLine();
            try {
                num = Integer.parseInt(input);
                if (num >= 0) {
                    return num;
                } else {
                    System.out.println("0 이상의 수를 입력해주세요.");
                }
            } catch (NumberFormatException e) {
                System.out.println("잘못된 입력입니다. 숫자만 입력해주세요.");
            }
        }
    }

    // 사칙연산 입력받기
    private static char getValidOperator(Scanner scanner) {
        while (true) {
            System.out.println("사칙연산(+, -, *, /)을 입력하세요: ");
            String operatorInput = scanner.nextLine();
            if (operatorInput.length() == 1 && "+-*/".indexOf(operatorInput.charAt(0)) != -1) {
                return operatorInput.charAt(0);
            } else {
                System.out.println("잘못된 입력입니다. 사칙연산 기호를 입력해주세요.");
            }
        }
    }

    // 계속 계산할지 묻기
    private static boolean getContinueInput(Scanner scanner) {
        while (true) {
            System.out.println("계속 계산하시겠습니까? (yes / exit): ");
            String continueInput = scanner.nextLine();
            if (continueInput.equalsIgnoreCase("exit")) {
                return false;
            } else if (continueInput.equalsIgnoreCase("yes")) {
                return true;
            } else {
                System.out.println("잘못된 입력입니다. 'yes' 또는 'exit' 를 입력해주세요.");
            }
        }
    }
}


// 추후에 추가할 것
// 속성, 생성자, 기능 주석 구분

// 괄호 사용
// 제곱
// Clear 기능
// 나누기 결과 소수점까지 표시

➡️

        Calculator calculator = new Calculator();

calculator 객체를 생성해주고,

// 사칙연산 수행 후 결과 출력
            int result = calculator.performCalculation(num1, num2, operator);

Calculator 클래스의 사칙연산 수행 메서드(performCalculation)를 호출해주고,
App 클래스 안의 사칙연산 수행 메서드는 깔끔하게 지워줬다


  • App 클래스의 main 메서드에서 Calculator 클래스의 연산 결과를 저장하고 있는 컬렉션 필드에 직접 접근하지 못하도록 수정(캡슐화)

    ✅ 간접 접근을 통해 필드에 접근하여 가져올 수 있도록 구현 (Getter 메서드)

    ✅ 간접 접근을 통해 필드에 접근하여 수정할 수 있도록 구현 (Setter 메서드)

    ✅ 위 요구사항을 모두 구현 했다면 App 클래스의 main 메서드에서 위에서 구현한 메서드를 활용해보자

package firstproject;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Calculator {

    // 연산 결과를 저장하는 컬렉션 필드
    private List<Integer> results;  // private 으로 설정하여 외부에서 직접 점근 불가

    // 생성자
    public Calculator() {
        results = new ArrayList<>();  // 연산 결과를 저장할 ArrayList 초기화
    }

    // 사칙연산 수행 메서드
    public int performCalculation(int num1, int num2, char operator) {
        int result;
        switch (operator) {
            case '+':
                result = num1 + num2;
                break;
            case '-':
                result = num1 - num2;
                break;
            case '*':
                result = num1 * num2;
                break;
            case '/':
                if (num2 != 0) {
                    result = num1 / num2;
                } else {
                    System.out.println("0으로 나눌 수 없습니다.");
                    return Integer.MIN_VALUE; // 에러 표시
                }
                break;
            default:
                System.out.println("잘못된 연산자입니다.");
                return Integer.MIN_VALUE; // 에러 표시
        }

        // 결과를 리스트에 저장
        results.add(result);
        return result;
    }

    // 연산 결과 리스트를 반환하는 getter 메서드
    public List<Integer> getResults() {
        return new ArrayList<>(results);  // results 의 복사본을 반환하여 외부에서 수정 못 하게 하기
    }

    // 연산 결과는 수정할 수 없지만, 연산 결과에 또 연산을 할 수 있는 setter 메서드
    // 마지막 연산 결과에 추가 연산 수행 메서드
    public int performAdditionalOperation(char operator, int number) {
        if (results.isEmpty()) {
            System.out.println("연산 결과가 없습니다. 먼저 계산을 수행해주세요.");

            // 계속 계산할지 묻기
            if (!getContinueInput()) {
                return Integer.MIN_VALUE;  // exit 를 입력하면 연산 종료
            } else {
                return Integer.MIN_VALUE;  // yes 를 입력하면 추가 연산 없이 프로그램 계속 실행
            }
        }

        int lastResult = results.get(results.size() - 1);  // 마지막 연산 결과 가져오기
        int result;

        // 마지막 연산 결과에 추가 연산 수행
        switch (operator) {
            case '+':
                result = lastResult + number;
                break;
            case '-':
                result = lastResult - number;
                break;
            case '*':
                result = lastResult * number;
                break;
            case '/':
                if (number != 0) {
                    result = lastResult / number;
                } else {
                    System.out.println("0으로 나눌 수 없습니다.");
                    return Integer.MIN_VALUE; // 에러 표시
                }
                break;
            default:
                System.out.println("잘못된 연산자입니다.");
                return Integer.MIN_VALUE; // 에러 표시
        }

        // 새로운 결과를 리스트에 저장
        results.add(result);
        return result;
    }

    // 계속 계산할지 묻기
    private boolean getContinueInput() {
        Scanner scanner = new Scanner(System.in);
        while (true) {
            System.out.println("계속 계산하시겠습니까? (yes / exit): ");
            String continueInput = scanner.nextLine();
            if (continueInput.equalsIgnoreCase("exit")) {
                return false;
            } else if (continueInput.equalsIgnoreCase("yes")) {
                return true;
            } else {
                System.out.println("잘못된 입력입니다. 'yes' 또는 'exit' 를 입력해주세요.");
            }
        }
    }
}

➡️

// 연산 결과를 저장하는 컬렉션 필드
    private List<Integer> results;

private 으로 설정하여 외부에서 직접 접근이 불가하도록 해주고,

// 연산 결과 리스트를 반환하는 getter 메서드
    public List<Integer> getResults() {
        return new ArrayList<>(results);

results의 복사본을 반환하여 외부에서 수정 못 하도록 하고,

    // 연산 결과는 수정할 수 없지만, 연산 결과에 또 연산을 할 수 있는 setter 메서드
    // 마지막 연산 결과에 추가 연산 수행 메서드
    public int performAdditionalOperation(char operator, int number) {
        if (results.isEmpty()) {
            System.out.println("연산 결과가 없습니다. 먼저 계산을 수행해주세요.");

            // 계속 계산할지 묻기
            if (!getContinueInput()) {
                return Integer.MIN_VALUE;  // exit 를 입력하면 연산 종료
            } else {
                return Integer.MIN_VALUE;  // yes 를 입력하면 추가 연산 없이 프로그램 계속 실행
            }
        }

연산 결과가 없을 경우, 에러 메시지 출력 후에 계산기 프로그램의 계속 진행/종료 여부를 물어보고,

int lastResult = results.get(results.size() - 1);  // 마지막 연산 결과 가져오기
        int result;

        // 마지막 연산 결과에 추가 연산 수행
        switch (operator) {
            case '+':
                result = lastResult + number;
                break;
            case '-':
                result = lastResult - number;
                break;
            case '*':
                result = lastResult * number;
                break;
            case '/':
                if (number != 0) {
                    result = lastResult / number;
                } else {
                    System.out.println("0으로 나눌 수 없습니다.");
                    return Integer.MIN_VALUE; // 에러 표시
                }
                break;
            default:
                System.out.println("잘못된 연산자입니다.");
                return Integer.MIN_VALUE; // 에러 표시
        }

        // 새로운 결과를 리스트에 저장
        results.add(result);
        return result;

마지막 연산 결과가 있고 추가 연산을 원할 경우, 추가 연산 진행을 위한 메서드를 추가해주고,

// 계속 계산할지 묻기
    private static boolean getContinueInput() {
        Scanner scanner = new Scanner(System.in);
        while (true) {
            System.out.println("계속 계산하시겠습니까? (yes / exit): ");
            String continueInput = scanner.nextLine();
            if (continueInput.equalsIgnoreCase("exit")) {
                return false;
            } else if (continueInput.equalsIgnoreCase("yes")) {
                return true;
            } else {
                System.out.println("잘못된 입력입니다. 'yes' 또는 'exit' 를 입력해주세요.");
            }
        }
    }

각 계산이 끝날 때마다 또 계산을 원하는지, 아니면 프로그램의 종료를 원하는지 물어보도록 마지막 부분에 코드 또 추가 (App 클래스에서 프로그램 종료 여부 묻는 코드 부분 가져온 다음 수정)

➡️ 수정한 코드를 실행해보니 추가 연산을 수행한 후에 또 추가 연산을 실행할지 물어보는 루프가 없어서 코드의 동작 흐름이 예상했던 것과 다르게 흘러갔다

내가 원한 건 추가 연산도 끝낼 때마다 계속 물어보길 원했기 때문에 다시 수정

package firstproject;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Calculator {

    private List<Integer> results;

    public Calculator() {
        results = new ArrayList<>();
    }

    // 사칙연산 수행
    public int performCalculation(int num1, int num2, char operator) {
        int result;
        switch (operator) {
            case '+': result = num1 + num2; break;
            case '-': result = num1 - num2; break;
            case '*': result = num1 * num2; break;
            case '/':
                if (num2 == 0) {
                    System.out.println("0으로 나눌 수 없습니다.");
                    return Integer.MIN_VALUE;
                }
                result = num1 / num2;
                break;
            default:
                System.out.println("잘못된 연산자입니다.");
                return Integer.MIN_VALUE;
        }
        results.add(result);
        return result;
    }

    // 마지막 연산 결과에 추가 연산 수행
    public int performAdditionalOperation(char operator, int number) {
        if (results.isEmpty()) {
            System.out.println("연산 결과가 없습니다. 먼저 계산을 수행해주세요.");
            return Integer.MIN_VALUE;
        }

        int lastResult = results.get(results.size() - 1);
        int result;

        switch (operator) {
            case '+': result = lastResult + number; break;
            case '-': result = lastResult - number; break;
            case '*': result = lastResult * number; break;
            case '/':
                if (number == 0) {
                    System.out.println("0으로 나눌 수 없습니다.");
                    return Integer.MIN_VALUE;
                }
                result = lastResult / number;
                break;
            default:
                System.out.println("잘못된 연산자입니다.");
                return Integer.MIN_VALUE;
        }

        results.add(result);
        return result;
    }

    // 유효한 숫자 입력받기
    public static int getValidNumber(String prompt, Scanner scanner) {
        while (true) {
            System.out.println(prompt);
            String input = scanner.nextLine();
            try {
                int num = Integer.parseInt(input);
                if (num >= 0) return num;
                else System.out.println("0 이상의 수를 입력해주세요.");
            } catch (NumberFormatException e) {
                System.out.println("잘못된 입력입니다. 숫자만 입력해주세요.");
            }
        }
    }

    // 유효한 연산자 입력받기
    public static char getValidOperator(Scanner scanner) {
        while (true) {
            System.out.println("사칙연산(+, -, *, /)을 입력하세요: ");
            String input = scanner.nextLine();
            if (input.length() == 1 && "+-*/".contains(input)) return input.charAt(0);
            else System.out.println("잘못된 입력입니다. 사칙연산 기호를 입력해주세요.");
        }
    }

    // 추가 연산 여부 묻기
    public static boolean askForAdditionalOperations(Scanner scanner) {
        while (true) {
            System.out.print("추가 연산을 하시겠습니까? (yes / exit): ");
            String input = scanner.nextLine();

            if (input.equalsIgnoreCase("exit")) {
                System.out.println("계산기를 종료합니다.");
                System.exit(0);  // 프로그램 종료
            } else if (input.equalsIgnoreCase("yes")) {
                return true;
            } else {
                System.out.println("잘못된 입력입니다.");
            }
        }
    }
}
package firstproject;

import java.util.Scanner;

public class App {

    public static Scanner scanner = new Scanner(System.in);

    public static void main(String[] args) {
        Calculator calculator = new Calculator();

        while (true) {
            // 첫 번째 숫자와 연산자 입력
            int num1 = Calculator.getValidNumber("첫 번째 숫자를 입력하세요: ", scanner);
            char operator = Calculator.getValidOperator(scanner);
            int num2 = Calculator.getValidNumber("두 번째 숫자를 입력하세요: ", scanner);

            // 첫 번째 연산 수행
            int result = calculator.performCalculation(num1, num2, operator);
            if (result != Integer.MIN_VALUE) {
                System.out.println("계산 결과: " + result);
            }

            // 추가 연산 여부 묻기
            if (result != Integer.MIN_VALUE && Calculator.askForAdditionalOperations(scanner)) {
                while (true) {
                    char additionalOperator = Calculator.getValidOperator(scanner);
                    int additionalNumber = Calculator.getValidNumber("숫자를 입력하세요: ", scanner);
                    result = calculator.performAdditionalOperation(additionalOperator, additionalNumber);
                    if (result != Integer.MIN_VALUE) {
                        System.out.println("추가 연산 결과: " + result);
                    }
                    if (!Calculator.askForAdditionalOperations(scanner))
                        break;
                }

                // 추가 연산을 계속할지 물어봄
                if (!Calculator.askForAdditionalOperations(scanner)) {
                    break;  // 더 이상 추가 연산을 원하지 않으면 루프를 종료
                }
            }
        }
    }
}

참고로 이때쯤 내 뇌는 이미 나의 것이 아니었..🫡🙃


다음에 추가해야 할 코드

  • Calcualtor 클래스에서 저장된 연산 결과들 중 가장 먼저 저장된 데이터를 삭제하는 기능을 가진 메서드를 구현한 후 App 클래스의 main 메서드에 삭제 메서드가 활용될 수 있도록 수정

    ⬜ 키워드 : 컬렉션

    ⬜ 컬렉션에서 '값을 넣고 제거하는 방법을 이해하는 것'이 중요!

profile
꾸준한 공부만이 답이다

0개의 댓글