Composition in Python
By: Cam Wohlfeil
Published: 2018-12-03 1300 EST
Modified: 2018-12-11 1130 EST
Category: Programming
Tags:
python
I'm a big fan of composition over inheritance in OOP, the only issue is that it's a bit harder to wrap your head around than basic inheritance. For a quick reminder, composition is simply aggregating objects together by making objects attributes of other objects. If an object has-a different object, then it is using a composition relationship. If an object is-a parent object, then it using an inheritance relationship.
class Student:
def __init__(self, name, student_number):
self.name = name
self.student_number = student_number
# A student has-a list of running courses
self.classes = []
def enroll(self, course_running):
self.classes.append(course_running)
course_running.add_student(self)
class Department:
def __init__(self, name, department_code):
self.name = name
self.department_code = department_code
# A department has-a list of courses
self.courses = {}
def add_course(self, description, course_code, credits):
self.courses[course_code] = Course(description, course_code, credits, self)
return self.courses[course_code]
class Course:
# Theoretical description of a course, i.e. what would be in a course catalog
def __init__(self, description, course_code, credits, department):
self.description = description
self.course_code = course_code
self.credits = credits
self.department = department
self.department.add_course(self)
# A course has-a list of running courses
self.runnings = []
def add_running(self, year):
self.runnings.append(CourseRunning(self, year))
return self.runnings[-1]
class CourseRunning:
# Concrete instance of a course, i.e. what would be in a student's schedule
def __init__(self, course, year):
self.course = course
self.year = year
# A running course has-a list of students
self.students = []
def add_student(self, student):
self.students.append(student)
math_dept = Department("Mathematics and Applied Mathematics", "MAM")
mam1000w = math_dept.add_course("Mathematics 1000", "MAM1000W", 1)
mam1000w_2018 = mam1000w.add_running(2018)
bob = Student("Bob", "Smith")
bob.enroll(mam1000w_2018)
References