✍️ 시작하며
이전 글에서는 객체지향 프로그래밍의 핵심 개념 중 하나인 상속(Inheritance) 을 통해
기존 클래스를 확장하는 방법과 메서드 오버라이딩에 대해 알아보았습니다.
이번 글에서는 클래스 간의 관계 중 하나인 포함 관계(Composition) 를 학습해보겠습니다.
포함 관계는 객체가 다른 객체를 "포함(has-a)" 하는 구조로,
자동차가 엔진을 가지듯, 집이 여러 방을 가지듯 객체 간 구성 관계를 표현할 때 사용됩니다.
💡 학습 목표
- 포함 관계(Composition)의 개념과 의미를 이해한다.
- "has-a" 관계와 "is-a" 관계를 비교할 수 있다.
- 포함 관계를 실제 코드로 구현하는 방법을 익힌다.
- 컴포지션의 생명주기 및 UML 표기법을 이해한다.
🧠 개념 정리
🔸 포함 관계(Composition)란?
포함 관계는 한 클래스가 다른 클래스를 자신의 필드(속성)로 포함하는 구조를 의미합니다.
이는 “has-a” 관계로 표현되며, 구성된 객체가 의존적이고 강한 생명주기 결합을 가질 때 사용합니다.
예를 들어,
- 자동차는 엔진을 “가지고 있다” → 포함 관계
- 집은 여러 개의 방을 “가지고 있다” → 포함 관계
→ 포함된 객체는 주 객체가 소멸되면 함께 소멸되는 강한 의존 관계입니다.

📑 문법 설명 – 포함 관계 vs 상속 관계 비교
| 구분 | 포함 관계 (Composition) | 상속 관계 (Inheritance) |
| 관계 표현 | "has-a" | "is-a" |
| 구현 방식 | 다른 클래스의 객체를 필드로 선언 | extends 키워드로 클래스 확장 |
| 생명주기 | 포함 객체는 소유 객체에 종속 | 자식 객체는 독립적으로 존재 가능 |
| 사용 예시 | 자동차 → 엔진, 집 → 방 | 학생 → 사람, 개발자 → 직원 |
| UML 표기 | 채워진 다이아몬드(◆) | 빈 삼각형(△) |
📌 예시 코드 ① – 자동차와 엔진 (자동 구성 포함 관계)
package com.composition;
public class Engine {
String name;
int price;
void start() {
System.out.println("엔진이 시작 됩니다.");
}
void stop() {
System.out.println("엔진을 멈춥니다.");
}
}
package com.composition;
public class Car {
String name;
int price;
// 포함관계(컴포지션)
// car 클래스는 Engine 객체를 포함 합니다.
Engine engine;
public Car() {
// 자동차 객체가 생성될 때 엔진 객체도 함께 생성 된다.
// 강한 의존성
engine = new Engine();
}
void startCar() {
engine.start(); // car 객체를 통해 Engine 의 start() 메서드를 호출합니다.
System.out.println("자동차가 출발합니다");
}
void stopCar() {
engine.stop();
System.out.println("자동차가 멈춥니다.");
}
// 테스트 코드 작성
public static void main(String[] args) {
// **컴포지션 관계를**
// 자동차 클래스 내부에서 엔진 객체를 생성 시켜야 콤포지션 관계이다.
Car car = new Car();
car.startCar();
car.stopCar();
} // end of main
}
✅ Car 클래스는 Engine 객체를 필드로 포함하고 있으며, Car가 생성될 때 Engine도 함께 생성됩니다.
📌 예시 코드 ② – 집과 방 구조 (House has-a Room[])
package com.composition;
public class Room {
private String type;
public Room(String type) {
this.type = type;
}
void describe() {
System.out.println(type + " 방입니다.");
}
}
package com.composition;
public class House {
private String address;
Room[] rooms;
public House(String address) {
this.address = address;
this.rooms = new Room[3]; // 컴포지션 : House 가 Room 배열을 소유하고 있다.
rooms[0] = new Room("거실");
rooms[1] = new Room("침실");
rooms[2] = new Room("주방");
// 속성으로 선언되고 내부에서 객체 생성 했기 때문에 컴포지션이라 할 수 있다.
//room = new Room("안방");
}
void showRooms() {
System.out.println( address + " 에 있는 방 목록 : ");
for(int i = 0; i < rooms.length; i++) {
if(rooms[i] != null) {
rooms[i].describe();
}
}
}
// 테스트 작성
public static void main(String[] args) {
House house = new House("부산시 진구");
house.showRooms();
// house 객체가 소멸이 되면 rooms 도 Room 객체도 소멸 (GC 에 의해 소멸)
house = null;
}
}
🧱 UML에서의 컴포지션 표현
클래스 다이어그램에서는 포함 관계를 채워진 다이아몬드(◆) 로 표현합니다.
+---------------------+
| House |
+---------------------+
| - address: String |
| - rooms: Room[] |
+---------------------+
| + House() |
| + showRooms() |
+---------------------+
◆ 1
|
|
| *
+---------------------+
| Room |
+---------------------+
| - type: String |
+---------------------+
| + describe() |
+---------------------+
- House → Room: 1:N 포함 관계
- House가 소멸되면 내부 Room들도 함께 사라짐 (강한 생명주기 결합)
📦 정리 표
항목 설명 포함 관계 한 클래스가 다른 클래스를 필드로 포함하는 관계 대표 표현 “has-a” 관계 생명주기 포함된 객체는 소유 객체와 함께 생성/소멸됨 구현 방법 필드로 선언 후 생성자 또는 내부에서 인스턴스화 UML 표현 채워진 다이아몬드(◆) 사용 사용 예시 자동차 → 엔진, 집 → 방, 회사 → 부서 등
🧩 마무리하며
이번 글에서는 클래스가 다른 클래스를 포함하여 구성하는 포함 관계(Composition) 에 대해 알아보았습니다.
자동차와 엔진, 집과 방처럼 객체가 객체를 소유하는 구조를 통해
객체 간의 강한 생명주기 결합을 어떻게 코드로 표현하는지 배웠습니다.
다음 글에서는 클래스 간의 연결을 나타내는 연관 관계(Association) 를 다루어보겠습니다.
포함 관계와 달리 객체 간 느슨한 연결이나 참조만 존재하는 관계는 어떻게 설계하는지 함께 살펴보겠습니다.
🔜 다음 글 예고 : 연관 관계(Association)
객체지향 설계에서 연관 관계는 클래스 간의 연결을 의미하며,
한 객체가 다른 객체를 참조하거나 사용하는 구조를 표현합니다.
다음 글에서는 연관 관계의 기본 개념과 단방향/양방향 연관, 그리고 실전 예제 코드를 통해 구조를 학습해보겠습니다.
🔙 이전 글 다시 보기
상속(Inheritance)에 대해서 궁금하다면??
🧱 상속(Inheritance)이란?
✍️ 시작하며이전 글에서는 같은 이름으로 다양한 매개변수를 처리하는 메서드 오버로딩(Overloading) 개념을 배웠습니다.이번 글에서는 객체지향 프로그래밍에서 가장 핵심적인 원칙 중 하나인
seohong.tistory.com
'Java' 카테고리의 다른 글
| 🧱 상속(Inheritance)이란? (1) | 2025.05.05 |
|---|---|
| 🧱 메서드 오버로딩이란? (0) | 2025.05.04 |
| 🧱 배열 복습하기 - 도서 관리 프로그램 (CRUD 실습) (0) | 2025.05.03 |
| 🧱 Array(배열)에 대한 이해 (0) | 2025.05.02 |
| 🧱 static 키워드에 대한 이해 (0) | 2025.05.01 |