B3.2.4

Explain the role of composition and aggregation in class relationships

In OOP, classes can relate in different ways:

2 min read395 words

Overview

In OOP, classes can relate in different ways:

  • is-a relationship (inheritance)
  • has-a relationship (aggregation)
  • part-of relationship (composition)

Composition and aggregation both model ownership/containment, but with different dependency strength.

Aggregation (has-a)

Aggregation is a weak ownership relationship:

  • One class contains or references another
  • Both objects can exist independently

Example from the notes:

  • Playlist has many Song objects
  • A Song can still exist without a specific Playlist

UML hint: aggregation is shown with a hollow diamond at the owner side.

Composition (part-of)

Composition is a strong ownership relationship:

  • One object is a required part of another
  • Part lifecycle depends on whole lifecycle
  • If the whole is deleted, its parts are deleted too

Example from the notes:

  • Book contains Chapter objects
  • Chapter does not meaningfully exist without its Book

UML hint: composition is shown with a filled diamond at the owner side.

Aggregation vs Composition

AspectAggregationComposition
Dependency strengthWeakStrong
Independent lifecycleYesNo
OwnershipShared/looseExclusive/strong
Delete whole objectParts may still existParts are typically removed
Common phrasehas-apart-of

Why This Matters in Design

  • Helps model real systems correctly (loose vs tight ownership)
  • Improves maintainability by clarifying responsibilities
  • Prevents lifecycle bugs (e.g., orphan objects or accidental shared state)
  • Makes UML and code structure consistent

Python Examples

1. Aggregation Example

class Song:
    def __init__(self, title: str):
        self.title = title


class Playlist:
    def __init__(self, name: str):
        self.name = name
        self.songs: list[Song] = []

    def add_song(self, song: Song):
        self.songs.append(song)


song = Song("Imagine")
playlist = Playlist("Favorites")
playlist.add_song(song)
# song can still exist even if playlist is deleted

2. Composition Example

class Chapter:
    def __init__(self, title: str):
        self.title = title


class Book:
    def __init__(self, title: str, chapter_titles: list[str]):
        self.title = title
        # chapters are created as an internal part of Book
        self.chapters = [Chapter(t) for t in chapter_titles]


book = Book("OOP Basics", ["Intro", "Classes", "Relationships"])

Start typing to search all published objectives.