본문 바로가기
ICIA 수업일지

2021.06.21 수업일지

by 주성씨 2021. 6. 26.

- 전화번호부 1단계

전화번호부 만들기 매인 클래스)

package phonebook;

public class PhoneBook {

	public static void main(String[] args) {
		PhoneInfo pInfo1 = new PhoneInfo("홍길동", "123-1234", "99/10/09");
		PhoneInfo pInfo2 = new PhoneInfo("이순신", "456-4567");
		
		pInfo1.showPhoneInfo();
		pInfo2.showPhoneInfo();

 

+ pInfo1.showPhoneInfo();와 같이도 출력 가능하지만

		System.out.println(pInfo1.toString()); //(인스턴스 참조값)
		System.out.println(pInfo2.toString()); // 모든 인스턴스는 참조값

+ 위와 toString(재정의)을 이용해서도 출력 가능하다.

+ 그리고 toString은 소스 오버라이드 임플리먼트를 통해서 재정의가 가능하다.

	} // method end

}// class end

전화번호부 만들기 서브 클래스)

package phonebook;

public class PhoneInfo {
	//필드
	private String name;
	private String phoneNum;
	private String birth;
	
	//생성자 1
	public PhoneInfo(String name, String phoneNum, String birth) {
		this.name=name;
		this.phoneNum=phoneNum;
		this.birth=birth;
	}
	
	//생성자 2
	public PhoneInfo(String name, String phoneNum) {
		this.name=name;
		this.phoneNum=phoneNum;
	}
	
    //인스턴스 메소드
	public void showPhoneInfo() {
		System.out.println("name : "+name);
		System.out.println("phonenum : "+phoneNum);
		if(birth!=null) {
			System.out.println("birth="+birth);
		}
	}
    // toString이 숨어있다.
	@Override //재정의. toString이 마음에 안들면 재정의가 가능.
	public String toString() {
		String str="";
		str+="name : "+name+"\n";
		str+="phoneNum : "+phoneNum+"\n";
		if(birth!=null) {
			str+="birth : "+birth;
		}
		str+="--------------";
		return str;
	}

+숨어있는 오버 라이딩을 통해서 재정의하여 위와 같이 나타낼 수도 있다.

+ \n을 통해서 줄을 바꿀 수 있다.

}// class end

 

예제 1)

package ex1;

public class Ex1_0621 {

	public static void main(String[] args) {
		System.out.println("강아지가\t 멍멍 짖는다.\n");
		System.out.println("고양이가\t 야옹 운다.\n");

+ \n, \t와 같은 것을 이스케이프 시퀀스라고 한다.

+ \n 한 칸 띄어쓰기

+ \t tap키만큼 띄어쓰기

		System.out.println("강아지가\t \"멍멍"\ 짖는다.\n");
		System.out.println("고양이가\t 야옹 운다.\n");

+ 문자열 중간에 \"멍멍\"을 통해서 더블 쿼터가 가능하다.

		System.out.println("c:\\down\\a.txt 열기");

+위와 같이 경로를 나타내고 싶을 때 순수하게 역슬래시를 사용하고 싶으면 두 번(\\) 쓰면 된다.

		int age=20;
		double height=170.4;
		String gender="남자";
		System.out.println("age = "+age);
		System.out.println("height = "+height);
		System.out.println("gender = "+gender);

+ 와 같이도 가능하지만 비효율적이기 때문에

		System.out.printf("age=%d\nheight=%f\ngender=%s\n",age,height,gender);

+ 와 같이 printf 메서드를 통해서 아래와 같이 출력할 수 있다.

+ %d 는 10진수 형태의 정수 값을 대입받는다.
%f 는 실수 값을 대입받는다.
%s 는 문자열을 대입받는다.
%.2f 는 소수점 둘째 자리까지 실수 값을 대입하여 출력해라.
%10d, %10s 는 10자리까지 오른쪽으로 정렬하라. -10은 왼쪽으로 정렬하라.


 

예제 2)
구구단을 printf를 통해서 한다면

		int dan = 5;
		int gob = 1;
		for(;gob<10;gob++) {
			System.out.printf("%d * %d = %d\n",dan,gob);
		}

결과)

5 * 1 = 5
5 * 2 = 10
5 * 3 = 15
5 * 4 = 20
5 * 5 = 25
5 * 6 = 30
5 * 7 = 35
5 * 8 = 40
5 * 9 = 45

 

- 표준 입력 출력 스트림

예제 3)

package ex1;

public class Ex2_0621 {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		String msg;
		System.out.print("메시지 입력 : ");
		msg = sc.next();
		System.err.println("msg = "+msg);

결과)

메시지 입력 : 동해물과 백두산이
msg = 동해물과

+위와 같이 '동해물과' 이후의 띄어쓰기는 입력이 안된다.

예제 3.1)

		Scanner sc = new Scanner(System.in);
		String msg;
		System.out.print("메시지 입력 : ");
		msg = sc.nextLine();
		System.err.println("msg = "+msg);

+이를 위하 nextLine을 사용해 입력값을 받으면

결과)

메시지 입력 : 동해물과 백두산이
msg = 동해물과 백두산이

+ 위와 같이 가능하다.


 

예제 4)

		Scanner sc = new Scanner(System.in);
		int num;
		String msg;
		System.out.print("정수 입력 : ");
		num = sc.nextInt();
		System.out.println("num = "+num);

		System.out.print("메시지 입력 : ");
		msg = sc.nextLine();
		System.err.println("msg = "+msg);

결과)

정수 입력 : 55
num = 55
메시지 입력 : msg = 

+ nextLine을 이용하면 입력값을 받지 않게 되는 현상이 일어난다. Why?

+ nextInt를 통해서 버퍼에 10을 쌓아놓은 후 CPU로 전달해 sysout으로 출력하면 10은 버퍼에서 사라진다.
하지만 10을 출력할 때 남아있던 엔터가 남아 있어서 nextLine의 특성상 띄어쓰기, 엔터 등을 입력받아 출력하기 때문에
메시지 입력에 받았던 데이터보다 먼저 입력되었던 것이 위와 같이 나온 것이다.
그래서 아래와 같이 해야 한다.

 

예제 4.1)

		Scanner sc = new Scanner(System.in);
		int num;
		String msg;
		System.out.print("정수 입력 : ");
		num = sc.nextInt();
		sc.nextLine();// 버퍼의 엔터를 삭제하기 위해서 입력
		System.out.println("num = "+num);
		System.out.print("메시지 입력 : ");
		msg = sc.nextLine();
		System.err.println("msg = "+msg);

결과)

정수 입력 : 55
num = 55
메시지 입력 : 동해물과 백두산이
msg = 동해물과 백두산이

+ sc.nextLine(); 버퍼의 엔터를 삭제하기 위해서 입력한다.


 

- 전화번호부 2단계

package phonebook;

import java.util.Scanner;

public class PhoneBook {
	// 필드
	public static Scanner key = new Scanner(System.in);
	// 스캐너 메서드를 어디서든 사용하고 싶을때는 class 아래에 두면 된다.
	// static 없으면 오류 뜨니 같이 사용한다. why?
	// 모든 패키지에서 사용하고 싶으면 public을 붙인다.

	// 컨트롤 타워
	public static void main(String[] args) {
		int menuNum;
		Scanner key = new Scanner(System.in);
		while (true) {
			showMenu();
			System.out.print("메뉴 입력 : ");
			menuNum = key.nextInt();
			switch (menuNum) {
			case 1:
				inputData();
				break;
			case 2:
				System.out.println("프로그램 종료");
				return; // 메인 메서드 종료
			// || System.exit(0); 시스템 강제 종료. 어느 메서드이든
			} // switch end

		} // while end

	} // method end
	private static void inputData() {
		System.out.print("이름 : ");
		String name = key.next();
		System.out.print("전화번호 :");
		String phoneNum = key.next();
		System.out.print("생년월일 : ");
		key.nextLine();
		String birth = key.nextLine();
		
		//인스턴스 생성
		PhoneInfo info = new PhoneInfo(name, phoneNum, birth);
		//임시로 인스턴스 값 출력
		info.showPhoneInfo();
	} // 인스턴스 메서드

	private static void showMenu() {
		System.out.println("메뉴를 입력하세요.");
		System.out.println("-------------");
		System.out.println("1. 데이터 입력");
		System.out.println("2. 프로그램 종료");
		System.out.println("-------------");
	} // 인스턴스 메서드
} // class end

 

- 전화번호부 3단계

	public static void main(String[] args) {
		PhoneBookManager manager=new PhoneBookManager(); //제어클래스
		int menuNum;

+ 컨트롤타워에 PhoneBookManager manager=new PhoneBookManager(); //제어 클래스를 추가한다.

// 컨트롤 타워
	public static void main(String[] args) {
		PhoneBookManager manager=new PhoneBookManager(); //제어클래스
		int menuNum;
		Scanner key = new Scanner(System.in);
		while (true) {
			showMenu();
			System.out.print("메뉴 입력 : ");
			menuNum = key.nextInt();
			switch (menuNum) {
			case 1:
				inputData();
				break;
			case 2:
				System.out.println("프로그램 종료");
				return; // 메인 메서드 종료
			// || System.exit(0); 시스템 강제 종료. 어느 메서드이든
			} // switch end

		} // while end

	} // method end

+ PhoneBookManager이라는 신규 클래스를 만든다.

package phonebook;
// 제어클래스
public class PhoneBookManager {
	final int MAX=100;
	PhoneInfo[] phoneList=new PhoneInfo[MAX];
	int cnt = 0;
	
	void inputData() {

		cnt++;
	}
	
	void searchData() {
		
	}
	
	void deleteData() {
		
	}
}

+ PhoneBook의 입력 데이터를 가져온다.

	void inputData() {
		System.out.print("이름 : ");
		String name = key.next();
		System.out.print("전화번호 :");
		String phoneNum = key.next();
		System.out.print("생년월일 : ");
		key.nextLine();
		String birth = key.nextLine();
		
		//인스턴스 생성
		PhoneInfo info = new PhoneInfo(name, phoneNum, birth);
		//임시로 인스턴스 값 출력
		info.showPhoneInfo();
		cnt++;
	}

+ 하지만 입력 스케너가 오류가 나기 때문에 PhoneBook.key. ~ 로 수정한다.

		System.out.print("이름 : ");
		String name = PhoneBook.key.next();
		System.out.print("전화번호 :");
		String phoneNum = PhoneBook.key.next();
		System.out.print("생년월일 : ");
		PhoneBook.key.nextLine();
		String birth = PhoneBook.key.nextLine();

+ 정보은닉을 위해 필드값을 수정한다.

	private PhoneInfo[] phoneList=new PhoneInfo[MAX];
	private int cnt = 0;

+ showMenu 를 예상 출력 값에 맞게 수정한다.

	private static void showMenu() {
		System.out.println("메뉴를 입력하세요.");
		System.out.println("-------------");
		System.out.println("1. 데이터 입력");
		System.out.println("2. 데이터 검색");
		System.out.println("3. 데이터 삭제");
		System.out.println("4. 프로그램 종료");
		System.out.println("-------------");
	} // 인스턴스 메서드

+ 이에 맞게 폰인포의 스위치를 확대시킨다.

			switch (menuNum) {
			case 1:
				manager.inputData();
				break;
			case 2:
				manager.searchData();
				break;
			case 3:
				manager.deleteData();
				break;
			case 4:
				System.out.println("프로그램 종료");
				return;

+ PhoneBookManager의 public void inputData()에 인스턴스 생성을 수정한다.

		//인스턴스 생성
		PhoneInfo info = new PhoneInfo(name, phoneNum, birth);
		phoneList[cnt]=info;
		cnt++;

+ 리스트를 보기 위해 private static void showMenu()에 다음과 같이 추가한다.

		System.out.println("3. 데이터 삭제");
		System.out.println("4. 데이터 리스트");
		System.out.println("5. 프로그램 종료");

+ 출력을 위해 스위치에 추가 후 인스턴스 메서드를 만든다.

			case 3:
				manager.deleteData();
				break;
			case 4:
				manager.showList();
				break;
			case 5:
				System.out.println("프로그램 종료");
				return;
	public void showList() {
		for(int i=0; i<cnt; i++)
			phoneList[i].showPhoneInfo();
	}

입력 후 임시 결과)

메뉴를 입력하세요.
-------------
1. 데이터 입력
2. 데이터 검색
3. 데이터 삭제
4. 데이터 리스트
5. 프로그램 종료
-------------
메뉴 입력 : 1
이름 : lee
전화번호 :111-2222
생년월일 : 20001010
메뉴를 입력하세요.
-------------
1. 데이터 입력
2. 데이터 검색
3. 데이터 삭제
4. 데이터 리스트
5. 프로그램 종료
-------------
메뉴 입력 : 1
이름 : park
전화번호 :222-3333
생년월일 : 20011010
메뉴를 입력하세요.
-------------
1. 데이터 입력
2. 데이터 검색
3. 데이터 삭제
4. 데이터 리스트
5. 프로그램 종료
-------------
메뉴 입력 : 4
name : lee
phonenum : 111-2222
birth : 20001010
---------------
name : park
phonenum : 222-3333
birth : 20011010
---------------
메뉴를 입력하세요.
-------------
1. 데이터 입력
2. 데이터 검색
3. 데이터 삭제
4. 데이터 리스트
5. 프로그램 종료
-------------
메뉴 입력 : 

+ public void searchData() 동명이인이 없다는 가정하에 검색 인스턴스 메서드 만들기

	public void searchData() {
		System.out.println("검색을 시작합니다.");
		System.out.println("이름 : ");
		String name=PhoneBook.key.next();
		
		for(int i=0; i<cnt; i++) {
			if(name.equals(phoneList[i].name)) //정보은닉을 피하기 위해 간점 생성
		}
	}

+ get set 메서드 만들기

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getPhoneNum() {
		return phoneNum;
	}

	public void setPhoneNum(String phoneNum) {
		this.phoneNum = phoneNum;
	}

	public String getBirth() {
		return birth;
	}

	public void setBirth(String birth) {
		this.birth = birth;
	}

+ getName을 추가하여 수정

	public void searchData() {
		System.out.println("검색을 시작합니다.");
		System.out.println("이름 : ");
		String name=PhoneBook.key.next();
		
		for(int i=0; i<cnt; i++) {
			if(name.equals(phoneList[i].getName())) {
			}
		}
	}

+ 동명이인이 없을 때 멈춰야 하니 break; 추가

		for(int i=0; i<cnt; i++) {
			if(name.equals(phoneList[i].getName())) {
				break; //이름이 동명이인이 없을때
			}
		}

+ 검색 결과를 보여줘야 하니 phoneList[i].showPhoneInfo();를 추가

		for(int i=0; i<cnt; i++) {
			if(name.equals(phoneList[i].getName())) {
				phoneList[i].showPhoneInfo(); // <--
				break; //이름이 동명이인이 없을때
			}
		}

+ 검색 결과가 없는 경우

		if(i==cnt) {
			System.out.println("존재하는 데이터가 없습니다.");
		}

+ public void deleteData() 삭제 메서드 만들기

		//삭제 메서드
		System.out.println("삭제를 시작합니다.");
		System.out.print("이름 : ");
		String name=PhoneBook.key.next();
		int i;
		for(i=0; i<cnt; i++) {
			if(name.equals(phoneList[i].getName())) {
				phoneList[i] = phoneList[cnt-1];
				cnt--;
				System.out.println("삭제 완료");
				break; //이름이 동명이인이 없을때
			}
		}
		//i==1 일때 삭제할 인스턴스를 찾음
		if(i==cnt) {
			System.out.println("삭제할 데이터가 없습니다.");
		}
	}

진도 나가기

- 상속

package ex1;

public class Person {
	// 필드
	private String name;
	private int age;

	// 인스턴스 메서드
	public void sleep() {
		System.out.println("사람은 보통 8시간 잔다.");
	}

	public void eat() {
		System.out.println("사람은 보통 세끼 먹는다.");
	}
} // class end

+ 펄슨 클래스의 메서드를 재활용하여 스투던트 클래스를 생성

package ex1;

public class Strudent {

	private Person p = new Person();
	private int schoolNum;
	
	public void fct() {
		p.eat();
		p.sleep();
	}
	
} // class end

+ 하지만 해당 클래스의 것이 아닌 것을 알아야 한다.

+ Person 클래스를 상속하기 위해서 다음과 같이 수정한다.

package ex1;

public class Strudent extends Person{ //Person 클래스를 상속하겠다!

	private int schoolNum;

} // class end

+ Person은 super class가 되고 Strudent는 sub class가 된다.

//	private String name;
//	private int age;
//	public void sleep() {
//	}
//	public void eat() {
//	}

+ 모두 자식의 것이 되며 다음과 같이 표현 가능하다.

package ex1;

public class Strudent extends Person { // Person 클래스를 상속하겠다!
//	private String name;
//	private int age;
	private int schoolNum;

//	public void sleep() {
//	}
//	public void eat() {
//	}
	public void study() {
		System.out.println("학생은 공부를 한다.");
	} // method end

} // class end

+ 메인 클래스를 만든다.

package ex1;

public class Main {

	public static void main(String[] args) {
		
		Student s1 = new Student("Lee",14,11);
		s1.showStudentInfo();
		
	}// main method end

}// class end

+ Student 클래스의 Student 인스턴스 상속자를 만든다.

+ showStudentInfo() 인스턴스 메서드를 만든다.

	public Student(String name, int age, int schoolNum) {
		this.name = name;
		this.age = age;
		this.schoolNum  = schoolNum;
	}
	public void showStudentInfo() {
		System.out.println("name = "+name);
		System.out.println("age = "+age);
		System.out.println("schoolNum = "+schoolNum);
	}

+ 하지만 name, age의 정보은닉 때문에 오류가 난다. (상속 < 정보은닉)

+ Person한테 받은 정보를 이용하기 위해서 Student class의 Student 생성자에 super();를 다음과 같이 적용한다.

	public Student(String name, int age, int schoolNum) {
		super(name,age); //생략 되어 있으며 부모 생성자 호출하라는 의미
		this.schoolNum  = schoolNum;
	}

+ super도 현재 작업적인 인스턴스를 가리키는 참조 변수이다.
Student는 Person 클래스의 상속자 이므로 생성자에 super();가 안 보이지만 생성되어 있다.


 

- 최종

- Main class

package ex1;

public class Main {

	public static void main(String[] args) {
		
		Student s1 = new Student("Lee",14,11);
		s1.showStudentInfo();
		
	}// main method end

}// class end

- Person class

package ex1;

public class Person {
	// 필드
	private String name;
	private int age;

	// 기본 생성자
	public Person() {
		System.out.println("Person()생성자");
	}

	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}

	// 인스턴스 메서드
	public void sleep() {
		System.out.println("사람은 보통 8시간 잔다.");
	}

	public void eat() {
		System.out.println("사람은 보통 세끼 먹는다.");
	}

	public void showPersonInfo() {
		System.out.println("name = "+name);
		System.out.println("age = "+age);
	}
} // class end

- Student class

package ex1;

public class Student extends Person { // Person 클래스를 상속하겠다!
	private int schoolNum;

	// 상속 < 정보은닉
	// 1. 부모생성자 실행
	// 2. 자식생성자 실행
	// 3. 인스턴스 실행
	public Student(String name, int age, int schoolNum) {
		super(name,age); //생략 되어 있으며 부모 생성자 호출하라는 의미
		this.schoolNum  = schoolNum;
	}
	
	public void study() {
		System.out.println("학생은 공부를 한다.");
	} // method end

	public void showStudentInfo() {
		showPersonInfo();
		System.out.println("schoolNum = "+schoolNum);
	}

} // class end

※ 인스턴스 생성과정의 이해
1. 메모리 공간의 할당
2. 상위 클래스의 생성자 실행
3. 하위 클래스의 생성자 실행
4. 인스턴스 생성

Q. 파트타임 학생의 신상과 일당을 출력하기 위해서 PartTimeStd를 만들고 출력

- class Main

package ex1;

public class Main {

	public static void main(String[] args) {
		
		Person p1 = new Person("Kim",20);
		p1.showPersonInfo(); // kim, 20 출력
		
		Student s1 = new Student("Lee",14,11);
		s1.showStudentInfo(); // lee, 14, 11출력
		
		PartTimeStd pts = new PartTimeStd("park", 22, 11, 8, 9000);
		pts.showPartTimeStdInfo(); // park, 22, 11, 64000원 출력
		
	}// main method end

}// class end

- class PartTimeStd

package ex1;

// 상속
public class PartTimeStd extends Student {
	// 필드
	private int hour; //일한 시간
	private int pay;
	
	// 생성자
	public PartTimeStd(String name, int age, int schoolNum, int hour, int pay) {
		super(name,age,schoolNum);
		this.hour=hour;
		this.pay=pay;
	}

	// 인스턴스 메서드
	public void showPartTimeStdInfo() {
		showStudentInfo();
		System.out.println("일당은 "+(hour*pay)+"입니다.");
	} //시간당 급여

}// class end

결과)

name = Kim
age = 20
name = Lee
age = 14
schoolNum = 11
name = park
age = 22
schoolNum = 11
일당은 72000입니다.

 

'ICIA 수업일지' 카테고리의 다른 글

2021.06.25 수업일지  (0) 2021.06.26
2021.06.24 수업일지  (0) 2021.06.26
2021.06.23 수업일지  (0) 2021.06.26
2021.06.22 수업일지  (0) 2021.06.26
2021.06.10 수업일지  (0) 2021.06.20