Composition and aggregation

Composition

Inheritance is used for is a relationships (e.g., a cat is an animal), and composition is used for has a relationships (e.g., a house has rooms). It involves attaching objects to a class instead of inheriting a whole class of these objects.


class Room:
    def __init__(self, name, area):
        self.name = name
        self.area = area

    def __str__(self):
        return f"{self.name} - area: {self.area}"

class House:
    def __init__(self):
        self.rooms = []

    def add_room(self, name, area):
        room = Room(name, area)
        self.rooms.append(room)

house = House()
house.add_room("Bedroom", 30)
house.add_room("Kitchen", 20)
house.add_room("Bathroom", 10)

for r in house.rooms:
    print(r)
                                    

In summary, we use inheritance when we want a class to inherit methods from a parent class and then modify or extend its functionalities. Inheritance allows us to override methods, but in the case of composition, we can only use them. When we need to use a class without any modifications, composition is recommended, and when we need to change the behavior of a method in another class, we use inheritance.

Aggregation

The difference between aggregation and composition is the degree of ownership of the existing class. Aggregation implies a relationship where the child class can exist independently of the parent class (cars are not a part of a car park). Example: school and students. Delete the school, and the students will still exist. Composition implies a relationship where the child cannot exist independently of the parent (e.g., wheels are a part of a car).


class Student:
    def __init__(self, name, surname):
        self.name = name
        self.surname = surname

    def __str__(self):
        return self.name + " " + self.surname

class School:
    def __init__(self, name):
        self.name = name
        self.students = []

    def add_student(self, student):
        self.students.append(student)

school = School("XYZ High School")
student1 = Student("John", "Smith")
student2 = Student("Kate", "Johnson")
student3 = Student("Jack", "Williams")

school.add_student(student1)
school.add_student(student2)
school.add_student(student3)

for s in school.students:
    print(s)

print(student1) # the students exist independently