2022.08.22 [MON]
- Day 16-
수업 주요 목차
- IO
- mini project : schoolproject-IO
🤖Review
Error : 구조개선, 환경 개선이 필요한 심각한 문제
Exception : 프로그램적으로 제어가 가능한 문제 (메세지 발생 JVM 즉시 종료) -> 예외 처리(Exception Handling)
예외 처리(Exception Handling) -> 대처방안 & 프로그램 정상 실행이 목적
try : 예외발생 예상영역 지정
catch : 예외 발생시 대처방안/대처흐름을 실행시켜 예외를 처리하는 영역
finally : 예외 발생여부, 처리여부와 상관없이 무조건 실행
throws : 예외를 호출한 측으로 전파(던지는 것)
throw : 필요시 예외를 의도적으로 발생시키는 것 (checked, unchecked 상관없음)
Checked : runtime 계열을 제외한 모든 exception (compile시 예외 체크 가능)
UnChecked : runtime 계열의 exception (throws 명시할 필요 없이 자동적으로 전파됨)
Polymorphism(다형성) : 하나의 메세지로 다양한 객체 참조할 수 있는 성질
Inheritance(상속) : 단일계층형성으로 다형성 환경을 지원한다. 부모의 멤버를 자식에게 물려준다.
Encapsulation(캡슐화) : 구현부, 소통부를 나누어 개발 / 소통부 공개 구현부 은닉 / 높은 응집도와 낮은 결합도의 고급 프로그램 개발/구현 가능하다.
Coupling(결합도) : 모듈간 상호 의존도
Cohesion(응집도) : 모듈 내 기능 집중도
Interface: 다양한 계층구조
abstract: 단일 계층구조 / 멤버 물려줌
공통점:
1) 직접 객체화될 수 없다.(단, 자식으로 부터 객체화 가능)
2) 부모 || 상위 타입으로 구조 계층 형성하여 다형성을 지원한다.
3) 자식에게 구현을 강제할 수 있다.
java memory
heap : 객체의 정보 저장(i.v)
stack : 로컬변수 저장 (l.v)
meta-space : 클래스 static
Overloading : 하나의 메소드, 다양한 매개변수 why? 클라이언트 편의성
Overriding : 부모의 method 상속받아 자신에 맞게 재정의
super - 부모를 가리킬 때
this - 나(자식)을 가리킬 때
Set : 중복 인정 안하는 데이터 관리
List: index로 데이터 관리
refactoring : 입출력 변화 없이 내부 구조를 바꾸는 것 ; 가독성을 높이기 위함
분석설계시 사용하는 기초 언어 : UML
** 15day **
if기반 ConsoleIO2를 switch구문으로 변경해보는 예제 제어문에서 label을 사용해본다.
Label : 반복문을 탈출 할 때 사용
label 을 지정하여 while문을 벗어나고 싶을 때 break label명을 써주면 된다.(label명은 자유롭게 지정)
package step1;
import java.util.Scanner;
public class TestConsoleIO3 {
Scanner scanner = new Scanner(System.in);
public void showMenu() {
exit:
while (true) {
System.out.println("***주종을 선택하세요 1.맥주 2.소주 3.막걸리 4.종료***");
String info = scanner.nextLine();
switch (info) {
case "1":
System.out.println("맥주 선택 완료");
break;
case "2":
System.out.println("소주");
break;
case "3":
System.out.println("막걸리");
break;
case "4": //label을 이용한다.
System.out.println("주문종료");
break exit; // 지정한 레이블이 명시된 제어문을 벗어난다.
//scanner.close(); -> 여기에 넣었더니 에러뜸
default:
System.out.println("입력값 오류");
}
//scanner.close(); -> 여기에 이걸 넣었더니 반복이 안되었었음
}
scanner.close();
}
public static void main(String[] args) {
new TestConsoleIO3().showMenu();
}
}
scanner.close() 위치 때문에 에러가 자주 났다. 위의 경우 메소드 밖에서 종료시켜줘야 함(계속 반복되어야 하는 곳에서 닫을 수 없고 선언 된 곳에서 끝내야 함)
근데 exit을 통해서 반복이 끝나고 종료가 되었는데 굳이 scanner까지 닫아줘야 하는 이유는 뭘까? 인터넷에 검색해보니 사용하지 않는 입출력 stream이 열리지 않도록 하기 위함이라고 하는데 저 예제에서 종료를 시켜 더 이상 입력이 불가능하게 되었는데도 굳이 닫아줘야하는 건 그냥...그냥 하는 건가...ㅋ.. 의례적인 그런..? stream 따로 한번 봐야겠다.
🔎 Eclipse 실습 내용
만들어뒀던 UML에 ConsoleUI 클래스를 따로 만들어서 어떻게 구현할지 다 같이 만들어봤다. 우선 매개변수로 scanner와 schoolservice 객체 생성해주고 method는 4가지로 나누었다. execute는 약간 메뉴같은 느낌이고 선택에 따라 SchoolService에 있는 method를 사용할 수 있도록 만들어 준다. 그 밑에 3가지는 메뉴의 구성요소(?)
Console class
package step2;
import java.util.Scanner;
import model.exception.DuplicateTelException;
import model.exception.MemberNotFoundException;
import model.service.SchoolService;
import model.vo.Employee;
import model.vo.Member;
import model.vo.Student;
import model.vo.Teacher;
public class ConsoleUI {
private SchoolService ss = new SchoolService();
private Scanner scanner = new Scanner(System.in);
execute method
public void execute() {
System.out.println("*******학사관리프로그램을 시작합니다******");
exit: while (true) {
System.out.println("1. 추가 2. 삭제 3. 검색 4. 전체회원보기 5.종료");
String info = scanner.nextLine();
switch (info) {
case "1":
addView();
break;
case "2":
deleteView();
break;
case "3":
findView();
break;
case "4":
ss.printAll();
break;
case "5":
System.out.println("******학사관리프로그램을 종료합니다******");
break exit;
default:
System.out.println("잘못된 입력값입니다.");
break;
}
}
scanner.close();
}
- 실행하자마자 "*******학사관리프로그램을 시작합니다******"메세지가 뜨고 메뉴 선택지가 "1. 추가 2. 삭제 3. 검색 4. 전체회원보기 5.종료" 이렇게 주어진다.
- 사용자가 입력하면 각각 그에 맞는 method가 실행될 수 있도록 만든다.
- 입력은 String으로 설정한 다음 "1~4"까지 각각 method를 실행할 수 있도록 써준다.
- "5"는 종료이기 때문에 반복문을 빠져나가도록 해야하는데 label을 이용하여 빠져나갈 수 있도록 한다.
- scanner는 프로그램이 종료하면서 입/출력할 수 없게 닫아줘야 하는데 scanner가 선언된 부분에서 닫아줘야 한다.
deleteView method
public void deleteView() {
while (true) {
System.out.println("삭제할 구성원의 전화번호를 입력하세요.");
String tel = scanner.nextLine();
try {
ss.deleteMemberByTel(tel);
System.out.println(tel + "에 해당하는 구성원을 삭제했습니다.");
} catch (MemberNotFoundException mnfe) {
System.out.println(mnfe.getMessage());
}
break;
}
}
- 사용자가 2번 삭제를 입력창을 통해 선택하면 "삭제할 구성원의 전화번호를 입력하세요" 메세지가 가장 먼저 뜨도록 한다.
- try, catch로 SchoolService에 있는 deleteMemberByTel method를 사용해서 삭제하고 만약 일치하는 정보가 없다면 catch 블럭에서 메세지를 호출한 측으로 전달
🤮실수🤮
while로 묶어놨었는데 그럴 필요가 없었음(삭제 메소드 안에 또 선택지가 있거나 메뉴가 있는게 아니니까!)
findView method
public void findView() {
System.out.println("조회할 구성원의 전화번호를 입력하세요.");
String tel = scanner.nextLine();
try {
ss.findMemberByTel(tel);
System.out.println(tel + " 조회결과: " + ss.findMemberByTel(tel));
} catch (MemberNotFoundException mnfe) {
System.out.println(mnfe.getMessage());
}
}
- 사용자가 3번 검색을 입력창을 통해 선택하면 "조회할 구성원의 전화번호를 입력하세요" 메세지가 가장 먼저 뜨도록 한다.
- 마찬가지로 try, catch 사용해서 SchoolService에 있는 findMemberByTel method를 사용해 결과를 출력해주도록 한다.
public void findView() {
System.out.println("조회할 구성원의 전화번호를 입력하세요.");
String tel = scanner.nextLine();
try {
Member member=ss.findMemberByTel(tel);
System.out.println(tel + " 조회결과: " + member);
} catch (MemberNotFoundException mnfe) {
System.out.println(mnfe.getMessage());
}
}
이렇게 member 변수 안에 참조시켜서 해도 됨!
자, 이제 대망의
addView method
public void addView() {
String tel, name, adress, id, sub, department, type = null;
while(true) {
System.out.println("입력할 구성원 종류를 선택하세요 1.학생 2.선생님 3.직원");
type=scanner.nextLine();
if(type.equals("1")||type.equals("2")||type.equals("3")) {
break;
}else {
System.out.println("1.학생 2.선생님 3.직원 중 하나를 선택하세요");
}
}
while (true) {
System.out.println("1. 전화번호를 입력하세요");
tel = scanner.nextLine();
if (ss.findIndexByTel(tel) != -1)
System.out.println("중복임");
else
break;
}
System.out.println("2. 이름를 입력하세요");
name = scanner.nextLine();
System.out.println("3. 주소를 입력하세요");
adress = scanner.nextLine();
Member member = null;
switch (type) {
case "1":
System.out.println("4. 학번을 입력하세요");
id = scanner.nextLine();
member = new Student(tel, name, adress, id);
break;
case "2":
System.out.println("4. 과목을 입력하세요");
sub = scanner.nextLine();
member = new Teacher(tel, name, adress, sub);
break;
case "3":
System.out.println("4. 부서를 입력하세요");
department = scanner.nextLine();
member = new Employee(tel, name, adress, department);
break;
}
try {
ss.addMember(member);
System.out.println("리스트에 추가: " + member.toString());
} catch (DuplicateTelException e) {
System.out.println(e.getMessage());
}
}
- add의 경우 이 안에서 3가지의 경우의 수(학생, 교사, 직원)가 생기기 때문에 while문으로 반복해서 돌려주고 "1", "2", "3" 이 선택되면 그만 반복되게, 그 외 다른 입력을 하게 되면 선택을 유도하는 메세지가 나오도록 한다.
- 전화번호 입력+중복확인은 3가지 경우의 수라도 모두 공통적으로 행해지는 과정이기 때문에 따로 빼서 중복이 아닐 때까지 반복해준다.
- SchoolService에 만들어뒀던 findIndexByTel을 이용한다.
- 중복 여부를 비교한 뒤 만약 있으면 메세지를, 없으면 반복을 중단한다.
- 전화번호로 중복 체크를 한 뒤 이름, 주소, 입력하는 것은 공통적이기 때문에 작성해주고 멤버객체를 생성한 뒤 null로 초기화해준다.
- case " 1"은 학생 저장용으로 학번을 마저 입력한다. ("2"는 교사/과목, "3"은 직원/부서)
- 모여진 데이터를 리스트에 추가하려고 할 때 중복을 다시 한 번 체크하고(사실상 불필요) 만약 예외가 있으면 catch에서 메세지를 전달하도록 해준다.
//오늘의 뿌듯한 점
멤버 리스트에 추가하고 확인 메세지 뜰 때 정보들 하나하나 써주는 걸로 맨 처음에 작성했다가 조금 생각해보니 이미 toString오버라이드 한게 있어서 그거 써먹어보려고 좀 끙끙댔더니 성공 멤버따로 생성자 생성해서 참조해주고 member.toString했더니 성공했다ㅏㅏㅏㅏ
// 오늘의 단축키
X
//오늘의 질문
X
//오늘의 숙제
복습+코드 한번 쳐보기