🧱 포함 관계(Composition)

2025. 5. 6. 21:15·Java
728x90

✍️ 시작하며

이전 글에서는 객체지향 프로그래밍의 핵심 개념 중 하나인 상속(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)에 대해서 궁금하다면??

2025.05.05 - [Java] - 🧱 상속(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
'Java' 카테고리의 다른 글
  • 🧱 상속(Inheritance)이란?
  • 🧱 메서드 오버로딩이란?
  • 🧱 배열 복습하기 - 도서 관리 프로그램 (CRUD 실습)
  • 🧱 Array(배열)에 대한 이해
공돌이 출신 개발자
공돌이 출신 개발자
공돌이 출신 개발자입니다
  • 공돌이 출신 개발자
    공돌이 출신 개발자
    공돌이 출신 개발자
  • 전체
    오늘
    어제
    • 분류 전체보기 (124)
      • Database (0)
        • SQL (0)
        • 1일 1쿼리 (9)
      • Flutter (40)
        • Dart 언어 (18)
        • App (22)
      • Git (0)
      • Http 기초 지식 (14)
      • HTML5 & CSS3 (0)
      • Java (33)
      • JSP (0)
      • JavaScript (0)
      • Linux (0)
      • MSA (0)
      • Project (0)
      • React (0)
      • Spring (19)
      • 설치 메뉴얼 (1)
      • [Flutter] 프로젝트 (눈길) (8)
        • 작업일지 (8)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • GitHub
  • 공지사항

  • 인기 글

  • 태그

    개발
    jsp
    프로그래밍
    객체
    dart
    SQLD
    HTTP
    데이터
    클래스
    flutter
    공부
    안드로이드
    JAVA 기초
    로그인
    코딩
    블로그 만들기
    1일1쿼리
    android studio
    앱개발
    회원가입
    Java
    안드로이드 앱 개발
    플러터
    spring boot
    SQL
    프로젝트
    객체지향
    앱 개발
    Android
    메서드
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.2
공돌이 출신 개발자
🧱 포함 관계(Composition)
상단으로

티스토리툴바