-
[과제] 계산기 Lv2내일배움캠프/과제 2025. 3. 6. 11:01
✅ Lv2. 클래스를 적용해 기본적인 연산을 수행할 수 있는 계산기 만들기
1️⃣ 과제 조건
- 사칙연산을 수행 후, 결과값 반환 메서드 구현 & 연산 결과를 저장하는 컬렉션 타입 필드를 가진 Calculator 클래스를 생성
- 사칙연산을 수행한 후, 결과값을 반환하는 메서드 구현
- 연산 결과를 저장하는 컬렉션 타입 필드를 가진 Calculator 클래스를 생성
- 1) 양의 정수 2개(0 포함)와 연산 기호를 매개변수로 받아 사칙연산(➕,➖,✖️,➗) 기능을 수행한 후 2) 결과 값을 반환하는 메서드와 연산 결과를 저장하는 컬렉션 타입 필드를 가진 Calculator 클래스를 생성.
- 예시코드
public class Calculator { /* 연산 결과를 저장하는 컬렉션 타입 필드 선언 및 생성 */ public 반환타입 calculate(...매개변수) { /* 위 요구사항에 맞게 구현 */ /* return 연산 결과 */ } }
- Lv 1에서 구현한 App 클래스의 main 메서드에 Calculator 클래스가 활용될 수 있도록 수정
- 연산 수행 역할은 Calculator 클래스가 담당
- 연산 결과는 Calculator 클래스의 연산 결과를 저장하는 필드에 저장
- 소스 코드 수정 후에도 수정 전의 기능들이 반드시 똑같이 동작해야함.
- 예시코드
public class App { public static void main(String[] args) { /* Calculator 인스턴스 생성 */ Scanner sc = new Scanner(System.in); /* 반복문 시작 */ System.out.print("첫 번째 숫자를 입력하세요:"); int num1 = sc.nextInt(); System.out.print("두 번째 숫자를 입력하세요:"); int num2 = sc.nextInt(); System.out.print("사칙연산 기호를 입력하세요: "); char operator = sc.next().charAt(0); /* 위 요구사항에 맞게 소스 코드 수정 */ System.out.println("더 계산하시겠습니까? (exit 입력 시 종료)"); ... /* 반복문 종료 */ } }
- 연산 수행 역할은 Calculator 클래스가 담당
- App 클래스의 main 메서드에서 Calculator 클래스의 연산 결과를 저장하고 있는 컬렉션 필드에 직접 접근하지 못하도록 수정 (캡슐화)
- 간접 접근을 통해 필드에 접근하여 가져올 수 있도록 구현. (Getter 메서드)
- 간접 접근을 통해 필드에 접근하여 수정할 수 있도록 구현. (Setter 메서드)
- 위 요구사항을 모두 구현 했다면 App 클래스의 main 메서드에서 위에서 구현한 메서드를 활용.
- 예시코드
public class Calculator { /* 연산 결과를 저장하는 컬렉션 타입 필드를 외부에서 직접 접근 하지 못하도록 수정*/ public 반환타입 calculate(...매개변수) { ... } /* Getter 메서드 구현 */ /* Setter 메서드 구현 */ } public class App { public static void main(String[] args) { /* Calculator 인스턴스 생성 */ Scanner sc = new Scanner(System.in); /* 반복문 시작 */ System.out.print("첫 번째 숫자를 입력하세요:"); int num1 = sc.nextInt(); System.out.print("두 번째 숫자를 입력하세요:"); int num2 = sc.nextInt(); System.out.print("사칙연산 기호를 입력하세요: "); char operator = sc.next().charAt(0); /* 위 요구사항에 맞게 소스 코드 수정 */ System.out.println("더 계산하시겠습니까? (exit 입력 시 종료)"); ... /* 반복문 종료 */ } }
- Calculator 클래스에 저장된 연산 결과들 중 가장 먼저 저장된 데이터를 삭제하는 기능을 가진 메서드를 구현한 후 App 클래스의 main 메서드에 삭제 메서드가 활용될 수 있도록 수정
- 키워드 : 컬렉션
- 컬렉션에서 ‘값을 넣고 제거하는 방법을 이해한다.’가 중요
- 예시코드
public class Calculator { /* 연산 결과를 저장하는 컬렉션 타입 필드를 외부에서 직접 접근 하지 못하도록 수정*/ public 반환타입 calculate(...매개변수) { ... } ... public void removeResult() { /* 구현 */ } } public class App { public static void main(String[] args) { /* Calculator 인스턴스 생성 */ Scanner sc = new Scanner(System.in); /* 반복문 시작 */ System.out.print("첫 번째 숫자를 입력하세요:"); int num1 = sc.nextInt(); System.out.print("두 번째 숫자를 입력하세요:"); int num2 = sc.nextInt(); System.out.print("사칙연산 기호를 입력하세요: "); char operator = sc.next().charAt(0); /* 위 요구사항에 맞게 소스 코드 수정 */ System.out.println("더 계산하시겠습니까? (exit 입력 시 종료)"); ... /* 반복문 종료 */ } }
- 키워드 : 컬렉션
2️⃣ 구현
while (true) { ... } private static String readInput(BufferedReader br) throws IOException { String input = br.readLine().trim(); if (input.equalsIgnoreCase(EXIT_COMMAND)) { System.out.println("계산기가 종료되었습니다."); System.exit(0); } return input; } // 양의 정수를 입력받는 메서드 (exit 입력 가능) private static int getPositiveInteger(BufferedReader br, String prompt) throws IOException { int number = -1; while (number < 0) { System.out.print(prompt); String input = readInput(br); try { number = Integer.parseInt(input); if (number < 0) { System.out.println("\n! 양의 정수를 입력해주세요 !\n"); } } catch (NumberFormatException e) { System.out.println("\n! 양의 정수를 입력해주세요 !\n"); } } return number; } // 올바른 사칙연산 기호를 입력받는 메서드 (exit 입력 가능) private static String getValidOperator(BufferedReader br) throws IOException { String operator = ""; while (!OPERATOR_LIST.contains(operator)) { System.out.print("사칙연산 기호를 입력하세요(+, -, *, /) : "); operator = readInput(br); } return operator; } // Y/N 입력을 받는 메서드 (exit 입력 가능) private static String getYesNoInput(BufferedReader br, String prompt) throws IOException { String input = ""; while (!YN_LIST.contains(input)) { System.out.print(prompt); input = readInput(br); } return input; }
getPositiveInteger(), getValidOperator(), getYesNoInput() 메서드를 생성하여 입력값을 받음.
공통으로 readInput() 함수를 생성하여 exit 가 입력되면 시스템이 종료되도록 변경
try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) { ... } catch (IOException e) { e.printStackTrace(); }
코드를 try-catch 를 활용하여 br을 선언해줌으로 br.close()를 사용하지 않아도 종료됨
public class Result { private int num1; private int num2; private String operator; private int result; }
연산 결과를 저장할 Result 객체를 만들어 놓고
public class Calculator { private int result; private List<Result> resultList = new ArrayList<>(); public void calculate(int num1, int num2, String operator) { // 사칙연산 기호에 따라 분기 this.result = switch (operator) { case "+" -> num1 + num2; case "-" -> num1 - num2; case "*" -> num1 * num2; case "/" -> num1 / num2; default -> throw new IllegalArgumentException(); // 올바르지 않은 값 입력 시 }; this.addResult(new Result(num1, num2, operator, this.result)); } }
사칙연산을 수행 후, 결과값 반환 메서드 구현 & 연산 결과를 저장하는 Calculator 클래스를 생성하여 기존 연산에 관련된 기능을 calculate 함수로 생성.
calcuate 에서는 연산 후 result 객체를 생성하여 list에 저장
if (resultYn.equalsIgnoreCase("Y")) { int i = 1; for (Result res : calculator.getResultList()) { System.out.println(i++ + ". " + res.toString()); } }
App 에는 기존 저장된 resulstList 의 결과를 볼 수 있는 기능을 구현
public class Calculator { public void removeResult(int index) { if (!resultList.isEmpty()) { resultList.remove(index - 1); } } }
if (removeYn.equalsIgnoreCase("Y")) { while (true) { System.out.print("삭제할 결과 번호를 입력하세요 : "); int index = Integer.parseInt(readInput(br)); int resultSize = calculator.getResultList().size(); if (index <= 0 || index > resultSize) { System.out.println("\n! 올바른 결과 번호를 입력해주세요 !\n"); continue; } calculator.removeResult(index); System.out.println("결과 값 삭제가 완료되었습니다."); break; } }
기존 결과 목록을 보고 삭제할 것인지 물어보아 해당 번호에 맞는 index 를 입력받아 삭제 시키도록 구현.
3️⃣ 정리
1. App 클래스 (메인 클래스)
App 클래스는 사용자로부터 입력을 받고, Calculator 클래스의 메서드를 호출하여 연산을 수행하는 역할.
- 입력 검증 및 반복 처리
- BufferedReader를 사용하여 입력을 받고, exit 명령어 혹은 Y/N 입력을 통해 계속 계산할지 여부를 확인.
- getPositiveInteger(), getValidOperator(), getYesNoInput() 메서드를 통해 입력값을 검증.
- Calculator 클래스 활용
- 사용자 입력이 올바르게 이루어지면, Calculator의 calculate() 메서드를 호출해 연산을 수행하고, 계산 결과를 컬렉션에 저장.
- 저장된 결과를 보고 싶을 때는 getResultList()로 가져와 출력하고, 삭제를 원할 경우 removeResult() 메서드를 호출하여 삭제할 수 있음.
2. Calculator 클래스
Calculator 클래스는 실제 연산을 수행하고 결과를 관리하는 역할.
여기서는 캡슐화를 적용해 연산 결과가 저장되는 리스트(resultList)에 외부에서 직접 접근하지 못하도록 했고, 필요 시 getter와 setter를 통해 간접적으로 접근할 수 있도록 구현.- calculate()
- 매개변수로 받은 두 정수와 사칙연산 기호에 따라 연산을 수행.
- switch 구문을 사용하여 각각의 연산을 처리하고, 계산 결과를 this.result에 저장.
- 계산된 결과를 새로운 Result 객체로 만들어 resultList에 추가.
- getResult() / setResult()
- 계산 결과를 읽거나 수정할 수 있도록 제공하는 getter와 setter.
- getResultList()
- 저장된 결과 리스트를 반환하는 getter.
- removeResult()
- 인덱스로 전달된 계산 결과를 리스트에서 삭제하는 메서드. (리스트 인덱스는 1부터 시작하는 사용자 입력을 보정하여 삭제)
3. Result 클래스
Result 클래스는 각 계산의 결과를 객체 형태로 저장하기 위해 사용.
여기서는 두 정수, 연산 기호, 그리고 계산 결과를 필드로 보관하고, toString() 메서드를 오버라이드하여 "num1 연산자 num2 = 결과" 형태의 문자열로 출력할 수 있도록 구현.4️⃣ 최종 코드
App
import java.io.*; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class App { // 상수로 문자열 관리 private static final String EXIT_COMMAND = "exit"; private static final List<String> OPERATOR_LIST = new ArrayList<>(Arrays.asList("+", "-", "*", "/")); private static final List<String> YN_LIST = new ArrayList<>(Arrays.asList("Y", "N", "y", "n")); public static void main(String[] args) { Calculator calculator = new Calculator(); try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) { System.out.println("계산기를 시작합니다."); System.out.println("계산기는 exit 입력 시 종료됩니다."); while (true) { try { int num1 = getPositiveInteger(br, "첫번째 양의 정수를 입력해주세요 : "); int num2 = getPositiveInteger(br, "두번째 양의 정수를 입력해주세요 : "); String operator = getValidOperator(br); // calculator 의 calculate 사용 calculator.calculate(num1, num2, operator); int result = calculator.getResult(); System.out.printf("%d %s %d = %d \n", num1, operator, num2, result); String resultYn = getYesNoInput(br, "기존 저장된 결과 값들을 보시겠습니까? (Y/N) : "); if (resultYn.equalsIgnoreCase("Y")) { int i = 1; for (Result res : calculator.getResultList()) { System.out.println(i++ + ". " + res.toString()); } } String removeYn = getYesNoInput(br, "기존 저장된 결과 값을 삭제하시겠습니까? (Y/N) : "); if (removeYn.equalsIgnoreCase("Y")) { while (true) { System.out.print("삭제할 결과 번호를 입력하세요 : "); int index = Integer.parseInt(readInput(br)); int resultSize = calculator.getResultList().size(); if (index <= 0 || index > resultSize) { System.out.println("\n! 올바른 결과 번호를 입력해주세요 !\n"); continue; } calculator.removeResult(index); System.out.println("결과 값 삭제가 완료되었습니다."); break; } } String continueYn = getYesNoInput(br, "계속 계산하시겠습니까? (Y/N) : "); if (continueYn.equalsIgnoreCase("N")) { break; } System.out.println(); // 개행 처리 } catch (NumberFormatException e) { System.out.println("\n! 정수를 입력해주세요 !\n"); } catch (IllegalArgumentException e) { System.out.println("\n! 올바른 사칙연산 기호를 입력해주세요 !\n"); } catch (ArithmeticException e) { System.out.println("\n! 나눗셈 연산에서 분모(두번째 정수)에 0이 입력될 수 없습니다 !\n"); } } System.out.println("계산기가 종료되었습니다."); } catch (IOException e) { e.printStackTrace(); } } // 입력을 읽고, exit 입력 시 프로그램 종료 private static String readInput(BufferedReader br) throws IOException { String input = br.readLine().trim(); if (input.equalsIgnoreCase(EXIT_COMMAND)) { System.out.println("계산기가 종료되었습니다."); System.exit(0); } return input; } // 양의 정수를 입력받는 메서드 (exit 입력 가능) private static int getPositiveInteger(BufferedReader br, String prompt) throws IOException { int number = -1; while (number < 0) { System.out.print(prompt); String input = readInput(br); try { number = Integer.parseInt(input); if (number < 0) { System.out.println("\n! 양의 정수를 입력해주세요 !\n"); } } catch (NumberFormatException e) { System.out.println("\n! 양의 정수를 입력해주세요 !\n"); } } return number; } // 올바른 사칙연산 기호를 입력받는 메서드 (exit 입력 가능) private static String getValidOperator(BufferedReader br) throws IOException { String operator = ""; while (!OPERATOR_LIST.contains(operator)) { System.out.print("사칙연산 기호를 입력하세요(+, -, *, /) : "); operator = readInput(br); } return operator; } // Y/N 입력을 받는 메서드 (exit 입력 가능) private static String getYesNoInput(BufferedReader br, String prompt) throws IOException { String input = ""; while (!YN_LIST.contains(input)) { System.out.print(prompt); input = readInput(br); } return input; } }
Calculator
import java.util.ArrayList; import java.util.List; public class Calculator { private int result; private List<Result> resultList = new ArrayList<>(); public void calculate(int num1, int num2, String operator) { // 사칙연산 기호에 따라 분기 this.result = switch (operator) { case "+" -> num1 + num2; case "-" -> num1 - num2; case "*" -> num1 * num2; case "/" -> num1 / num2; default -> throw new IllegalArgumentException(); // 올바르지 않은 값 입력 시 }; this.addResult(new Result(num1, num2, operator, this.result)); } public int getResult() { return result; } public void setResult(int result) { this.result = result; } public List<Result> getResultList() { return resultList; } public void addResult(Result result) { resultList.add(result); } public void removeResult(int index) { if (!resultList.isEmpty()) { resultList.remove(index - 1); } } }
Result
public class Result { private int num1; private int num2; private String operator; private int result; public Result(int num1, int num2, String operator, int result) { this.num1 = num1; this.num2 = num2; this.operator = operator; this.result = result; } @Override public String toString() { return num1 + " " + operator + " " + num2 + " = " + result; } }
'내일배움캠프 > 과제' 카테고리의 다른 글
[과제] 키오스크 필수 Lv3 (0) 2025.03.13 [과제] 키오스크 필수 Lv2 (1) 2025.03.13 [과제] 키오스크 필수 Lv1 (0) 2025.03.13 [과제] 계산기 Lv3 (1) 2025.03.06 [과제] 계산기 Lv1 (1) 2025.03.05 - 사칙연산을 수행 후, 결과값 반환 메서드 구현 & 연산 결과를 저장하는 컬렉션 타입 필드를 가진 Calculator 클래스를 생성