22.1 What is Containment?
Containment is an OOP concept where one class contains another class inside it. In simple terms, a big object is made from smaller objects.
A common phrase used to describe containment is:
- A car has an engine
- A school has many students
- A house has rooms
This “has-a” relationship helps you build programs that are organised, easy to understand, and close to real-life situations.
| Term | Meaning |
|---|---|
| Containment (aggregation) | An OOP concept where one class contains another class inside it. A big object is made from smaller objects. |
| has-a relationship | The phrase that describes containment: A has-a B (a car has an engine). |
| Composition | A strong form of containment where the contained object cannot exist without the main object (created inside). |
| Aggregation | A weaker form of containment where the contained object can exist on its own (passed in, not created inside). |
| Container class | The class that holds other objects (e.g. School, Library, Car). |
| Component class | The class that is held inside (e.g. Student, Book, Engine). |
- Containment is a has-a relationship: one class contains another class inside it.
- A big object is made from smaller objects.
22.1 What is Containment?
22.2 Why Containment Matters — and vs Inheritance
Containment helps you in four ways:
- Break a large problem into smaller parts — instead of making one giant class, you create smaller, focused classes and combine them.
- Improve readability — each class handles one job, so your code becomes cleaner.
- Reuse classes — once you create a class like Engine or Student, you can use it in other programs.
- Model real-world objects — most real things are made up of smaller things. OOP tries to match this natural structure.
Students often confuse containment with inheritance. They are completely different concepts, and both are required in good program design:
| Inheritance (is-a) | Containment (has-a) |
|---|---|
| A relationship like "is-a" | A relationship like "has-a" |
| Example: A Dog is an Animal | Example: A Dog has a Tail |
| The child class reuses the parent's attributes and methods | The container class holds an object of another class as an attribute |
- Examiners test whether you can tell has-a (containment) from is-a (inheritance).
- “A Dog is an Animal” is inheritance; “A Dog has a Tail” is containment.
- Mixing these up loses easy marks.
22.2 Containment vs Inheritance
22.3 A Simple Example: Car and Engine
Let us start with an easy example that matches real life. A car cannot work without an engine. The car is the main object; the engine is a part inside it.
class Engine:
def __init__(self, horsepower):
self.horsepower = horsepower
class Car:
def __init__(self):
self.engine = Engine(150) # Car contains an Engine
my_car = Car()
print(my_car.engine.horsepower) # 150The Car object contains an Engine object. When you create a Car, the Engine is automatically created inside it. This is containment — and because the Engine is created inside the Car, it is also composition.
- The container class creates an object of the component class inside its constructor:
self.engine = Engine(150). - When you create the container, the component is automatically created inside it.
- Battery: def __init__(self, capacity): self.capacity = capacity.
- Phone: def __init__(self): self.battery = Battery(3000).
- Main: p = Phone(); print(p.battery.capacity).
22.3 A Simple Example: Car and Engine
22.4 Containment with Multiple Objects
Containment can also mean “has many”. A library contains many book objects; a school contains many students. You store them in a list inside the container class.
class Book:
def __init__(self, title):
self.title = title
class Library:
def __init__(self):
self.books = [] # a list of Book objects
def add_book(self, book):
self.books.append(book)
# usage
b1 = Book("Hamlet")
b2 = Book("Macbeth")
lib = Library()
lib.add_book(b1)
lib.add_book(b2)
for b in lib.books:
print(b.title)- Containment with many objects uses a list:
self.books = []. - The
add_bookmethod appends each object:self.books.append(book). - This models “has many”.
- Step 1 — Student class with name and grade.
- Step 2 — School class with self.students = [].
- Step 3 — add_student(self, student): self.students.append(student).
- Step 4 — create two Students, a School, add them, loop and print.
- Mirror the School/Student pattern: self.modules = [], add_module appends.
- In the Cambridge-style
Course/Moduleexample, a course is made of several modules. - If the
Courseobject is destroyed, all modules inside it are also removed. - This is a strong form of containment known as composition.
22.4 Composition vs Aggregation
22.5 Types of Containment: Composition vs Aggregation
There are two types of containment. The difference is whether the contained object can exist on its own.
| Type | Main idea | Code pattern | Example |
|---|---|---|---|
| Composition | Object is created inside another object. The contained object cannot exist without the main object. | self.part = Part() | Car and Engine |
| Aggregation | Object is passed into another object. The contained object can exist on its own. | self.parts.append(existing_part) | School and Students |
- The
Carclass creates theEngineitself. - The
Enginecannot exist meaningfully without theCar. - The
Carfully controls theEngine's lifetime.
# Composition
class Heart:
def __init__(self):
self.beats_per_minute = 72
class Human:
def __init__(self):
self.heart = Heart() # Created inside the class
h = Human()
print(h.heart.beats_per_minute) # 72- House creates the Rooms inside __init__: self.rooms = [Room("Bedroom"), Room("Kitchen"), Room("Living Room")].
- Loop over my_house.rooms and print room.room_type.
- Mirror the House/Rooms pattern: Car creates the Wheels inside __init__.
Studentobjects are created outside theSchool.- They can exist without being part of any
School. - The
Schoolonly “collects” them.
# Aggregation
class Student:
def __init__(self, name):
self.name = name
class School:
def __init__(self):
self.students = [] # Not created inside the class
def add_student(self, student):
self.students.append(student)
s1 = Student("Amina") # created outside the School
s2 = Student("Hasib") # created outside the School
my_school = School()
my_school.add_student(s1)
my_school.add_student(s2)
for s in my_school.students:
print(s.name)- Teachers are created outside the School and passed in — this is aggregation.
- School: self.teachers = [], add_teacher appends.
- Books are created outside the Library and passed in — aggregation.
- Composition: the object is created inside (
self.part = Part()) and cannot exist without the main object. - Aggregation: the object is passed in (
self.parts.append(existing_part)) and can exist on its own.
22.6 How Containment Appears in Exams
In Cambridge exam questions, containment is usually tested in four forms:
- Understanding relationships — identify whether a relation is “has-a” or “is-a”.
- Drawing class diagrams — you may be given a scenario and asked to draw classes with links.
- Writing classes — write classes that contain other classes.
- Explaining the difference — explain the difference between composition, aggregation, and inheritance.
(a) State whether the relationship between School and Teacher is “has-a” or “is-a”. [1]
(b) Write program code to declare a Teacher class with a constructor that takes a name and a subject. [3]
(c) Write program code to declare a School class with a constructor that takes a name and sets up an empty list of teachers, and an add_teacher method. [4]
(d) Explain whether this is composition or aggregation, giving a reason. [2]
- (a) has-a (a school has teachers).
- (b) class Teacher: __init__(self, name, subject) storing both as attributes.
- (c) class School: __init__(self, name) with self.teachers = []; add_teacher(self, teacher) appends.
- (d) aggregation — teachers are created outside the school and passed in, so they can exist on their own.
✓ Key Points Summary
22.7 Practice Tasks
Fifteen exam-style tasks. Click Hint for bullet-point guidance, then Help to reveal a worked Python solution.
Question Bank
Answer all questions, then press Submit Quiz to see your score.
Question 1Multiple Choice
Containment in OOP means:
Question 2Multiple Choice
Which is a has-a relationship?
Question 3True / False
Inheritance is an is-a relationship; containment is a has-a relationship.
Question 4Multiple Choice
In composition, the contained object is:
Question 5Multiple Choice
In aggregation, the contained object is:
Question 6Multiple Choice
Which is an example of composition?
Question 7Multiple Choice
Which is an example of aggregation?
Question 8True / False
In composition, if the main object is destroyed, the contained object is also destroyed.
Question 9Multiple Choice
How does a School class store multiple Student objects?
Question 10Multiple Choice
Why is containment useful?
Question 11Multiple Choice
In the Car/Engine example, when is the Engine created?
Question 12Multiple Choice
How does containment appear in Cambridge exams?
Answer all 12 questions to enable submission.