할아버지도 쉽게 이해하는 JAVA 클래스 (2) 배열 및 참조 호출 | dasfef

2023.04.06

개인 기록용 입니다 :) 오타, 수정 등 피드백 환영

참조: JAVA 클래스 (1)
call by reference 활용
하루의 할 일을 표현하는 Day 클래스를 활용하여 MonthSchedule 클래스를 작성해보자 참조문헌 : 명품자바프로그래밍

public class Day {
	private String work;
	public void set(String work) {this.work = work;}
	public String get() {return work;}
	public void show() {
		if(work == null) System.out.println("없습니다");
		else System.out.println(work + "입니다");
	}
}


Day 클래스를 하나씩 살펴보자


이 함수를 건드리지 않고 MonthSchedule 클래스를 작성해보자

문제의 요구 1 입력시 » 날짜 선택 날짜 선택 후 » 할일 메모
2 입력시 » 날짜 선택 날짜 선택 후 » 해당 날짜의 할일 메모 불러오기
3 입력시 » 프로그램 종료
Day 클래스는 건드리지 않고 진행
자바 클래스 (1) 에서의 설명을 활용하면 크게 어려운 점은 없다

1, 2, 3 을 선택하는 명령을 main 에 작성 후 switch 를 활용하여 메뉴 선택을 하고 해당하는 기능들에 따라 메소드 생성해주면 끝
많이 연습하는 메뉴 생성 프로그램과 크게 다른 점은 없지만 객체 지향 프로그래밍으로 전환할 뿐인것 같다

전체 코드
import java.util.InputMismatchException;
import java.util.Scanner;

public class MonthSchedule {
	static Scanner scan = new Scanner(System.in);
	static Day day = new Day();
	static int date = 0;
	
	// 날짜 선택 메소드
	public static int date() {
		System.out.print("날짜(1~30) >>");
		int date = scan.nextInt();
		return date;
	}
	
	// 할일 입력 메소드
	public static void input() {
		System.out.print("할일(빈칸없이 입력) >>");
		String work = scan.next();
		day.set(work);
	}
	
	// 할일 불러오기 메소드
	public static void view(int a) {
		System.out.print(a + "일의 할 일은 "); day.show();
	}
	
	public static void main(String[] args) {
		
		System.out.println("이번달 스케줄 관리 프로그램");
		while(true) {
			try {
				System.out.print("할일(입력:1, 보기:2, 끝내기:3) >> ");
				int _num = scan.nextInt();
				if(_num <= 3 && _num > 0) {
					switch(_num) {
					case 1:
						date = date();
						input();
						break;
						
					case 2:
						date = date();
						view(date);
						break;
						
					case 3:
						System.out.println("프로그램 종료.");
						return;
						
					default :
						System.out.println("잘못된 선택입니다. 다시 선택하세요.");
						continue;
					}
				}
			}
			catch(InputMismatchException e) {
				System.out.println("숫자로만 선택해주세요. 다시 선택하세요.");
				scan.next();
			}
		}
	}
}


예외처리 한부분이 추가되어 추가 설명 후 넘어가자면

try / catch 를 활용해 try 에서 시도되는 명령에서 오류가 발생한다면 해당 오류는 catch 구문과 같이 잡아줄 수 있다
catch 구문 뒤에 예외처리문을 작성하고 catch 발동시 실행할 명령 작성
만일 위와 같이 try / catch 를 하지 않고 일반적으로 작성한 뒤, 메뉴 선택에 있어 문자열을 입력한다면

위와 같이 오류가 발생한다
반대로 try / catch 문을 활용해 오류 발생시 명령을 작성해주면

오류 없이 진행된다

배열 및 참조 호출 다음과 같이 작동하는 클래스를 작성해보자 참조 : 명품자바프로그래밍

>> 인원수 입력
인원수에 맞게 이름과 번호 기입란 출력
검색할 이름 검색  동일한 이름이 있다면 이름과 번호 출력
"그만" 입력시 프로그램 종료.


우선 이름과 번호를 받을 수 있는 클래스를 생성해보자

public class Phone {
	String name;
	String tel;
	
	// 매개변수 반환 생성자
	public Phone(String name, String tel) {
		this.name = name;
		this.tel = tel;
	}
	
	// 기본 생성자
	public Phone() {	}
}

Phone 이라는 이름의 클래스 생성, 매개변수가 들어올 때의 생성자와 기본 생성자를 만들어준다
이후 PhoneBook 이라는 클래스를 생성하고 메인 메소드부터 차례대로 진행해보자

메인 메소드
public class PhoneBook {
	static Scanner scan = new Scanner(System.in);
    static int people = 0;

	public static void main(String[] args) {
		System.out.print("인원수 >> ");
		people = scan.nextInt();
		Phone book[] = new Phone[people];
	}
}

인원수 » 출력후 해당하는 수에 맞게 배열을 생성해준다
Phone 클래스 중 각각의 인덱스에 이름과 번호를 같이 넣을 예정이니 Phone 클래스를 book[] 배열로 지정
이름과 번호를 기입받을 메소드를 생성해준다

public static void input(Phone book[]) {
    
    for (int i = 0; i < people; i++) {
        System.out.print("이름과 전화번호(이름과 번호는 빈 칸없이 입력) >> ");
        String name = scan.next();
        String tel = scan.next();
        book[i] = new Phone(name, tel);
    }
}

Scanner.next() 를 활용해서 공백을 구분하여 이름과 번호로 기입될 수 있게끔 스캔해주고 name, tel 이라는 변수로 지정한다
for 문을 활용해서 book(Phone 클래스의 배열) 의 0번부터 인원수로 입력받은 people 만큼의 인덱스에 이름과 번호를 같이 넣어준다
이때 input 에 들어갈 매개변수는 Phone 클래스의 book 배열을 넣어준다

검색 기능 메소드
public static void Search(Phone book[]) {
    while(true) {
        System.out.print("검색할 이름 >>");
        String name = scan.next();
        if(name.equals("그만")) {
            System.out.println("프로그램 종료.");
            break;
        }
        Phone.search(book, name);
    }
}

반복해서 검색을 해야하기 때문에 while 반복문 안에 넣어주고
새로운 변수 name 에 해당 이름을 저장 if 문을 활용해 name 변수에 있는 값이 “그만” 이면 프로그램 종료
아니라면 Phone 클래스의 search 메소드로 넘어가게 만들어준다

Phone 클래스
public static void search(Phone book[], String n) {
    String result_name = null;                        // 빈 String 변수 생성
    String result_tel = null;                         // ""
    String failure = null;                            // ""
    boolean flag = true;                              // 스위치 역할
    for (int i = 0; i < book.length; i++) {
        if(book[i].name.equals(n)) {                  // PhoneBook 클래스에서 넘어온 n(=name)
            result_name = n;                          // 빈 변수에 값 저장
            result_tel = book[i].tel;                 // ""
            flag = false;                             // 스위치 ON
        }
        else
            failure = "존재하지 않는 이름입니다\n";
        
    }
    
    if (flag == false) {                              // 스위치 ON 발동시
        System.out.printf("%s 의 번호는 %s 입니다\n", result_name, result_tel);
    }
    else System.out.println(failure);
}

빈 String 변수 생성 후 for 문 활용하여 PhoneBook 클래스에서 받아 넘어온 book[] 배열과 n 을 활용한다
Phone 클래스의 book[0] 의 name 이 PhoneBook 클래스의 검색에서 넘어온 n(=name) 과 같다면 비어있는 String 변수에 해당 값을 저장 후 boolean flag 변수를 false 로 바꾸어 스위치 역할을 하게 한다
스위치가 켜졌다면 아래 명령으로 내려와 if(flag == false) 명령을 실행하게 한다
​그리고 다시 main 에 만들어 준 메소드를 호출만 해주면 올바르게 시행된다

전체 코드 / Phone
public class Phone {
	String name;
	String tel;
	
	// 매개변수 반환 생성자
	public Phone(String name, String tel) {
		this.name = name;
		this.tel = tel;
	}
	
	// 기본 생성자
	public Phone() {	}

	public static void search(Phone book[], String n) {
		String result_name = null;
		String result_tel = null;
		String failure = null;
		boolean flag = true;
		for (int i = 0; i < book.length; i++) {
			if(book[i].name.equals(n)) {
				result_name = n;
				result_tel = book[i].tel;
				flag = false;
			}
			else
				failure = "존재하지 않는 이름입니다\n";
			
		}
		
		if (flag == false) {
			System.out.printf("%s 의 번호는 %s 입니다\n", result_name, result_tel);
		}
		else System.out.println(failure);
		
	}
}


전체 코드 / PhoneBook
import java.util.Scanner;

public class PhoneBook {
	static Scanner scan = new Scanner(System.in);
	static int people = 0;
	
	public static void input(Phone book[]) {
		
		for (int i = 0; i < people; i++) {
			System.out.print("이름과 전화번호(이름과 번호는 빈 칸없이 입력) >> ");
			String name = scan.next();
			String tel = scan.next();
			book[i] = new Phone(name, tel);
		}
	}
	
	public static void Search(Phone book[]) {
		while(true) {
			System.out.print("검색할 이름 >>");
			String name = scan.next();
			if(name.equals("그만")) {
				System.out.println("프로그램 종료.");
				break;
			}
			Phone.search(book, name);
		}
	}
	
	public static void main(String[] args) {
		System.out.print("인원수 >> ");
		people = scan.nextInt();
		Phone book[] = new Phone[people];
		input(book);
		Search(book);
	}

}


[ 회고 ]

  1. Search 기능은 Phone 클래스 말고 PhoneBook 에서 했어도 될것 같다
  2. 덕지덕지 붙는 빈 변수 말고 다른 방법을 찾아 메모리 효율을 높이고 싶었는데 아직 효율적인 코드 작성에 있어선 능률이 부족하다
  3. 배열에 있어선 이해가 좋지만 call by reference 부분에 약한 모습을 많이 보인다
  4. C 에서도 마찬가지인 모습이 보여 관련된 문제에 대한 능숙함이 요구된다