
상속(IS-A)만이 객체 간의 관계가 아니다. "학생은 학교에 다닌다", "자동차는 엔진을 가진다"처럼 객체끼리 서로 참조하거나 포함하는 관계도 있다. 이번 글에서는 연관, 포함, 집합 관계를 정리해본다.
두 객체가 서로 알고 있는 관계다. 한 클래스가 다른 클래스를 필드로 가지거나 메서드 매개변수로 받는 방식으로 표현한다.
public class Student {
String name;
School school; // Student가 School을 참조
public Student(String name, School school) {
this.name = name;
this.school = school;
}
}
public class School {
String name;
public School(String name) {
this.name = name;
}
}
School school = new School("한국대학교");
Student student = new Student("김민수", school);
Student와 School은 서로 독립적으로 존재할 수 있다. 학생이 사라져도 학교는 그대로고, 학교가 사라져도 학생 객체 자체는 남는다.

"전체-부분" 관계지만, 부분이 전체 없이도 독립적으로 존재할 수 있다.
public class Team {
String name;
List<Player> players; // Team이 Player를 포함
public Team(String name) {
this.name = name;
this.players = new ArrayList<>();
}
public void addPlayer(Player player) {
players.add(player);
}
}
public class Player {
String name;
public Player(String name) {
this.name = name;
}
}
Player p1 = new Player("이민준");
Player p2 = new Player("박서준");
Team team = new Team("FC서울");
team.addPlayer(p1);
team.addPlayer(p2);
팀이 해체(삭제)되어도 선수 객체 p1, p2는 그대로 존재한다. 선수는 팀과 독립적이다.
"전체-부분" 관계이고, 부분이 전체 없이 독립적으로 존재할 수 없다.
public class Car {
private Engine engine; // Car가 Engine을 소유
public Car() {
this.engine = new Engine(); // Car가 직접 Engine 생성
}
}
public class Engine {
int horsepower;
}
Car 안에서 Engine을 직접 생성한다. Car가 사라지면 Engine도 함께 사라진다. Engine은 Car 없이 의미가 없다.
| 관계 | 생명주기 | 독립성 | 예시 |
|---|---|---|---|
| 연관 (Association) | 독립적 | 독립 가능 | 학생 - 학교 |
| 집합 (Aggregation) | 부분이 독립적 | 부분 독립 가능 | 팀 - 선수 |
| 포함 (Composition) | 전체에 종속 | 부분 독립 불가 | 자동차 - 엔진 |
핵심 질문: "전체가 사라지면 부분도 사라지는가?"
상속(IS-A)은 "강아지는 동물이다"처럼 종류의 관계를 표현한다. 반면 연관/포함/집합(HAS-A)은 "자동차는 엔진을 가진다"처럼 소유나 참조 관계를 표현한다. 상속보다 포함 관계를 적극 활용하면 더 유연한 설계가 된다.