티스토리 뷰

이번 글에서는 Main 클래스 외에 두 개의 클래스를 더 가지는 예제를 살펴본다. 두 클래스 간에 서로 관계를 가지는 경우 그것을 객체 참조로 나타내고자 한다.

다음과 같이 학생 정보를 입력받아 출력을 내보내는 프로그램을 작성해 보자.

입력 파일

결과 출력 형태
1 lee f A
2 kim m B
3 choi m C
4 park f A
5 kang m B
[1] lee (녀) – A팀
[2] kim (남) – B팀
[3] choi(남) – C팀
[4] park(녀) – A팀
[5] kang(남) – B팀

여기서는 학생 클래스 하나만 있고 다섯개의 객체가 생성되어 리스트에 저장될 것이다.

그런데 자바 프로그램에서 꼭 데이터를 입력받지 않아도 클래스가 될 수 있는데, 다음과 같이 팀 정보를 출력하고자 한다면 팀 객체를 생성할 수 있을 것이다. 꼭 입력과 출력이 아니어도 나중에 팀에 관련해서 프로그램의 기능을 확장해야 한다면 클래스로 만들어야 할 것이다.

A -[lee, park]
B -[kim, kang]
C -[choi]

 이러한 클래스가 가져야 할 필드를 결정하는 것은 비교적 쉽다. 팀의 이름과 멤버 리스트를 가져야 할 것이다. 여기서 멤버 리스트를 학생으로 저장해 두고 싶다.

class Team { 
    String name;
    ArrayList<Student> members = new ArrayList<>();
    
}

이런 팀 객체를 모은 전체리스트는 Main 클래스가 가질 것이다. (학생이나 팀을 관리하는 일은 메인 클래스의 역할이다.) 먼저 생각해 봐야 하는 것은 팀을 언제 만들 것인가다. 그리고 팀의 members를 어떻게 채워넣을 것인가도 문제다.

팀을 만드는 것은 Student의 팀 이름이 입력될 때마다 하나씩 만들어져야 하는데 여러 학생이 같은 팀인 경우 하나의 팀만 만들어져야 한다. 이런 문제를 해결하는 방법으로 Main 클래스에서 팀을 찾는 메소드에 다음과 같은 슈도코드를 쓸 수 있다. 이미 그 이름의 팀이 있으면 그것을 돌려주고 없으면 새로 팀을 만든다. 새로 만든 팀은 메인의 팀리스트에 추가되어야 할 것이다.

ArrayList<Team> teams = new ArrayList<>();
Team getTeam(String name) {		// 이름에 대한 팀을 찾아 돌려주는 메소드
    for (Team t : teams)		// 현재 있는 팀들 중에
        if (t.matches(name))		// 그 이름에 매치되는 것이 있으면
            return t;			// 그 팀을 반환
    Team tm = new Team(name);		// 없으면 그 이름의 팀을 새로 만들어서 반환
    teams.add(tm);			// 새로 만든 팀을 메인의 전체 팀리스트에 넣는다
    return tm;
}

그럼 이 코드를 이용하여 다음과 같이 Student의 read 메소드를 수정할 수 있다.

void read(Scanner scan, Main main) {	// 메인 객체를 매개변수로 받는다
    아이디, 이름, 성별 읽어들이는 부분;
    String teamName = scan.next();	// 팀 이름을 읽고
    Team t = main.getTeam(teamName);	// main의 getTeam을 호출해 팀을 받아온다
    team = t;				// 이 학생의 팀을 t로 저장한다. (이름 대신 팀 객체)
    team.addMember(this);		// 그 팀의 멤버로 이 학생을 추가한다
}

이제 학생은 팀을 가지고 팀은 학생 리스트를 가지고 있는 객체들이 만들어졌다. 이걸 잘 출력하고 검색하게 각자 프로그램을 완성해 보자.

다음으로 학생이 여러 팀에 소속될 수 있는 경우를 생각해 보자. 이번에는 입력파일이 좀 바뀌어서 학생이 팀을 가지고 있지 않고 팀이 소속 학생 아이디를 가지고 있다.

1 lee f
2 kim m
3 choi m
4 park f
5 kang m
0

A 1 2 3 0
B 3 5 0
C 2 3 4 5 0
D 1 2 0
[1] lee (녀) - [A, D]
[2] kim (남) - [A, C, D]
[3] choi(남) - [A, B, C]
[4] park(녀) - [C]
[5] kang(남) - [B, C]
A -[lee, kim, choi]
B -[choi, kang]
C -[kim, choi, park, kang]
D -[lee, kim]

이런 형태의 입력과 출력을 위해서는 학생 클래스의 필드가 좀 바뀌어야 한다. 일단 학생이 팀을 여러개 가질 수 있어야 한다. 또한 팀을 만드는 것은 입력을 받으면서 하면 되므로 앞에서 썼던 방법으로 팀을 그때그때 만들어줄 필요는 없다.

대신 팀을 입력할 때 팀을 만들고 아이디로 학생을 찾아서 팀의 members에 넣어주는 것 이외에 그 학생의 소속팀 리스트에 자신(this)을 넣어야 한다. 이런 일을 이번에는 팀의 read에서 해야 한다.

void read(Scanner scan, Main main) {	// 메인 객체를 매개변수로 받는다
    이름 읽어들이는 부분;
    int n = scan.nextInt();		// 학생 아이디를 읽고
    Student st = main.findStudent(n);	// main의 findStudent을 호출해 학생을 받아온다
    members.add(st);			// 이 학생을 members에 추가한다.
    st.myteams.add(this);		// 나를 그 학생의 팀 리스트에 추가한다
}

 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
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
글 보관함