실습문제
5. 더하기(+), 빼기(-), 곱하기(*), 나누기(/)를 수행하는 각 클래스 Add, Sub, Mul, Div와 main() 메소드를 담은 클래스를 만들어, 계산을 수행하는 프로그램을 짜보자. main() 메소드에서는 키보드로부터 두 정수와 계산하고자 하는 연산자를 입력받아, 객체생성을 통해 연산을 수행하여 결과를 출력한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | import java.util.Scanner; interface AboutCalculate{ public void setValue(int a, int b); public int calculate(); } class Add implements AboutCalculate{ int a; int b; public void setValue(int a, int b) { this.a = a; this.b = b; } public int calculate() { int result = a + b; return result; } } class Sub implements AboutCalculate{ int a; int b; public void setValue(int a, int b) { this.a = a; this.b = b; } public int calculate() { int result = a-b; return result; } } class Mul implements AboutCalculate{ int a; int b; public void setValue(int a, int b) { this.a = a; this.b = b; } public int calculate() { int result = a*b; return result; } } class Div implements AboutCalculate{ int a; int b; public void setValue(int a, int b) { this.a = a; this.b = b; } public int calculate() { System.out.println("모든 나눗셈 연산은 몫만 출력되어, 정수로 나타납니다."); int result = a/b; return result; } } public class CalculateProgram { public static void main(String[] args) { System.out.println("두 정수와 연산자를 입력하시오. >> "); Scanner scanner = new Scanner(System.in); int num1 = scanner.nextInt(); int num2 = scanner.nextInt(); char op = scanner.next().charAt(0); switch(op) { case '+' : Add add = new Add(); add.setValue(num1, num2); int addresult = add.calculate(); System.out.println(addresult); break; case '-' : if(num1 >= num2) { Sub sub = new Sub(); sub.setValue(num1, num2); int subresult = sub.calculate(); System.out.println(subresult); break; } else { System.out.println("첫번째 정수가 두번째 정수보다 크거나 같아야합니다. 프로그램을 종료합니다."); break; } case '*' : Mul mul = new Mul(); mul.setValue(num1, num2); int mulvalue = mul.calculate(); System.out.println(mulvalue); break; case '/' : if (num1 >= num2) { Div div = new Div(); div.setValue(num1, num2); double divvalue = div.calculate(); System.out.println(divvalue); } else { System.out.println("첫번째 정수가 두번째 정수보다 크거나 같아야합니다. 프로그램을 종료합니다."); break; } } } | cs |
클래스를 이용하여 짤 수 있는 정말 간단한 문제이다. 원래 실습 문제는 인터페이스 사용을 요구하지 않았지만, 4개의 연산 클래스들이 모두 같은 메소드를 가질수 있다는 점을 이용하여, 추상메소드를 가진 인터페이스를 두고 각 클래스들이 이를 구현하면 전반적인 구조를 잡고 코드에 제약을 두기에 좋을 것이다. (가독성 측면)
이 코드의 결과는 다음과 같다.
부가적으로, 뺄셈이나 나눗셈에서 첫번째 수와 두번째 수에 대한 제약으로 경고문을 넣었고, 나눗셈에서 정수 출력에 관한 부분에도 안내문을 출력하도록 하였다. 원래 나눗셈은 몫과 나머지 모두를 출력해주고 싶었으나, 인터페이스에서 calculate()의 리턴 타입을 이미 int로 지정해놓았기 때문에 불가능했다. 그렇게 하려면 인터페이스 implement를 포기해야하는데, 통일성을 위해 그냥 int로 리턴하였다.
6. 간단한 공연 예약 시스템을 만든다. 공연예약 시스템은 다음과 같은 조건을 만족시켜야 한다.
- 공연은 하루에 한 번 있다.
- 좌석은 S석, A석, B석 타입이 있으며 모두 10석의 좌석이 있다. (하지만 나는 출력물을 따라 S: 10석, A: 15석, B: 20석을 할당하였다.)
- 공연 예약 시스템의 메뉴는 "예약", "조회", "취소", "끝내기"가 있다.
- 예약은 한 자리만 가능하고 좌석 타입, 예약자 이름, 좌석 번호를 순서대로 입력받아 예약한다.
- 조회는 모든 종류의 좌석을 표시한다.
- 취소는 예약자 이름을 입력하여 취소한다.
- 없는 이름, 없는 번호, 없는 메뉴, 잘못된 취소 등에 대해서 오류 메시지를 출력하고 사용자가 다시 시도하도록 한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 | import java.util.Scanner; class Reserve_Seat{ Scanner s = new Scanner(System.in); String[] sSeat = new String[10]; String[] aSeat = new String[15]; String[] bSeat = new String[20]; Reserve_Seat(){ //생성자 (초기화) int i = 0; while(i<20) { if (i<10) sSeat[i] = "---"; if (i<15) aSeat[i] = "---"; bSeat[i] = "---"; i++; } } public void show_reserve() { //조회메뉴 System.out.print("S>> "); for(int i=0; i<sSeat.length; i++) { System.out.print(sSeat[i] + " "); } System.out.println(); System.out.print("A>> "); for(int i=0; i<aSeat.length; i++) { System.out.print(aSeat[i] + " "); } System.out.println(); System.out.print("B>> "); for(int i=0; i<bSeat.length; i++) { System.out.print(bSeat[i] + " "); } System.out.println(); } public boolean show_oneline(int inputseats) { //지정 라인 좌석만 보여주기 switch(inputseats) { //사용자 입력값 받은 파라미터 case 1: //s좌석 보여주기 System.out.print("S>> "); for(int i=0; i<sSeat.length; i++) { System.out.print(sSeat[i] + " "); } System.out.println(); return true; case 2: //a좌석 보여주기 System.out.print("A>> "); for(int i=0; i<aSeat.length; i++) { System.out.print(aSeat[i] + " "); } System.out.println(); return true; case 3: //b좌석 보여주기 System.out.print("B>> "); for(int i=0; i<bSeat.length; i++) { System.out.print(bSeat[i] + " "); } System.out.println(); return true; default : //1~3 사이의 숫자 입력 안했을 경우 System.out.println("잘못 입력하였습니다. 다시 입력해주세요."); return false; } } public void reservation() { //예약메뉴 int inputseat = 0; String name = ""; boolean right; while(true) { System.out.print("좌석구분 S<1>, A<2>, B<3> >> "); inputseat = s.nextInt(); right = show_oneline(inputseat); //입력한 좌석 보여주기 if(right == false) continue; //다시 좌석 선택 System.out.print("이름 >> "); name = s.next(); System.out.print("번호 >> "); int seatnum = s.nextInt(); try { switch(inputseat) { case 1: sSeat[seatnum-1] = name; break; case 2: aSeat[seatnum-1] = name; break; case 3: bSeat[seatnum-1] = name; break; } } catch(ArrayIndexOutOfBoundsException e) { System.out.println("없는 좌석번호입니다. 다시 입력해주세요."); continue; } System.out.println(); return; } } public void del_reserve() { //예약 취소 int delete = 0; boolean right; String delname = ""; int count; //예약 취소 요청한 이름이 없는 이름인지 있는 이름인지 판별 while(true) { count = 0; //이 코드가 while 밖에 있으면 count가 계속 쌓여감. System.out.print("좌석구분 S<1>, A<2>, B<3> >> "); delete = s.nextInt(); right = show_oneline(delete); //입력한 좌석 보여주기 if(right = false) continue; //다시 좌석 선택 System.out.print("이름 >> "); delname = s.next(); switch(delete) { //예약 취소 case 1: for(int i=0; i<sSeat.length; i++) { if(sSeat[i].equals(delname)) { sSeat[i] = "---"; } else count += 1; } if (count == 10) { System.out.println("예약되지 않은 이름입니다. 다시 시도해주세요."); continue; } break; case 2: for(int i=0; i<aSeat.length; i++) { if(aSeat[i].equals(delname)) aSeat[i] = "---"; else count += 1; } if (count == 15) { System.out.println("예약되지 않은 이름입니다. 다시 시도해주세요."); continue; } break; case 3: for(int i=0; i<bSeat.length; i++) { if(bSeat[i].equals(delname)) bSeat[i] = "---"; else count += 1; } if (count == 20) { System.out.println("예약되지 않은 이름입니다. 다시 시도해주세요."); continue; } break; } //switch문 System.out.println(); return; } } } //--메인 메뉴-- public class ReserveSystem { public static void main(String[] args) { int menu = 0; Scanner scanner = new Scanner(System.in); Reserve_Seat rs = new Reserve_Seat(); while(true) { System.out.println("************공연 예약 시스템************"); System.out.println(); System.out.println("예약<1>, 조회<2>, 취소<3>, 끝내기<4> "); System.out.println("==================================="); System.out.print("어떤 메뉴를 이용하시겠습니까? "); menu = scanner.nextInt(); switch(menu) { case 1 : rs.reservation(); break; case 2: rs.show_reserve(); break; case 3: rs.del_reserve(); break; case 4: System.out.println("시스템을 종료합니다."); return; default: System.out.println("없는 메뉴입니다. 다시 입력해주세요."); } } } } | cs |
코드를 구현하면서 내 코드가 너무 더럽다는 걸 너무 많이 느꼈다. 하지만 아직 개발 공부 자체도 많이 한게 아니기 때문에 리팩토링에 관한 부분은 내가 더 많은 코드를 짜보면서 배우게 될 것이라 믿는다..
어쨌든 이 실습문제의 코드는 다음과 같은 출력물을 내면 된다.
예외처리 : InputMismatchException
Exception in thread "main" java.util.InputMismatchException
1 2 3 4 5 6 7 | public class TestError{ public static void main(String[] args) { int menu = 0; Scanner scanner = new Scanner(System.in); menu = scanner.nextInt(); } | cs |
위의 실습 코드에 약간의 변형을 주어 아주 간단하게 추려보았다. 코드에서는 사용자가 입력한 정수값이 menu에 저장됨을 나타내는 데, 여기서 InputMismatchException이 발생한다면 사용자는 정수가 아닌 실수나 문자열 등을 입력했기 때문이다.
하지만 내 경우에는 올바른 범위 내의 정수만 계속 입력해줬는데도 exception 에러가 발생했다. 그 이유는 Scanner#nextInt() 메소드는 사용자 입력의 마지막 개행문자를 제거해주지 않기 때문인데, 즉, 사용자가 입력한 정수와 '엔터'까지 입력값으로 받아들였기 때문에 이 에러가 발생한 것이다.
해결
1 2 3 4 5 6 7 | public class TestError{ public static void main(String[] args) { int menu = 0; Scanner scanner = new Scanner(System.in); menu = Integer.ParseInt(scanner.nextLine()); } | cs |
이 에러에 대한 해결은 아주 간단히, 입력받은 String을 Integer#ParseInt() 를 통해 정수로 변환시켜준다.
'Programming > Java' 카테고리의 다른 글
명품 java programming 실습문제 : 인터페이스(3번), 추상클래스(6번) (2) | 2018.11.20 |
---|---|
명품 java programming open challenging : 상속 관계의 클래스 작성(ProductInfo) (0) | 2018.11.18 |
명품 java programming open challenging : 끝말잇기 게임 만들기 (0) | 2018.11.07 |
명품 java programming 실습문제 : 반복문과 배열 그리고 예외처리 (1) | 2018.09.27 |
명품 java programming open challenging : 카드 번호 맞추기 게임 (260) | 2018.09.27 |