Association of objects in python
As per my last article on relationships between objects in python we learned that in object-oriented programming, association is the common term for both the has-a and part-of relationships. But has-a and part-of relationships are also termed as Aggregation and Composition. Lets dive in to know more. 😊
Aggregation
In aggregation, we create a relationship between two classes where one class has a reference object of another class. The lifetime of the owned object does not depend on the lifetime of the owner class. If the owner object gets deleted, the owned object can continue to exist in the program lifecycle. Let see an example
class Country:
def __init__(self, name=None, population=0):
self.name = name
self.population = population
def printDetails(self):
print("Country Name:", self.name)
print("Country Population", self.population)
class Person:
def __init__(self, name, country):
self.name = name
self.country = country
def printDetails(self):
print("Person Name:", self.name)
self.country.printDetails()
c = Country("Wales", 1500)
p = Person("Joe", c)
p.printDetails()
# deletes the object p
del p
print("")
c.printDetails()
output
Person Name: Joe
Country Name: Wales
Country Population 1500
Country Name: Wales
Country Population 1500
In the example above, there is a Country class and Person class, each person is associated with a country, but country itself can exist without person, when we delete the Person object p, the country object still exists. This is what known as aggregation, it creates a weaker relationship by having a reference to an object.
Composition
In Composition, a class owns an object of another class, the lifetime of the owned object depends on the lifetime of the owner, the owned object is a part of owner class. Let see an example
class Engine:
def __init__(self, capacity=0):
self.capacity = capacity
def printDetails(self):
print("Engine Details:", self.capacity)
class Tires:
def __init__(self, tires=0):
self.tires = tires
def printDetails(self):
print("Number of tires:", self.tires)
class Doors:
def __init__(self, doors=0):
self.doors = doors
def printDetails(self):
print("Number of doors:", self.doors)
class Car:
def __init__(self, eng, tr, dr, color):
self.eObj = Engine(eng)
self.tObj = Tires(tr)
self.dObj = Doors(dr)
self.color = color
def printDetails(self):
self.eObj.printDetails()
self.tObj.printDetails()
self.dObj.printDetails()
print("Car color:", self.color)
car = Car(1600, 4, 2, "Grey")
car.printDetails()
output
Engine Details: 1600
Number of tires: 4
Number of doors: 2
Car color: Grey
In the example above, a car is composed of engine,tires,doors. In this case, the Car class is an owner class and Engine,Tires,Doors are owned class. Car class contains the object of engines,tires,doors and controls the lifetime of the objects. Once the Car object is removed the objects of engines,tires,doors are also removed. This is what known as composition, it creates a tight relationship by having instances of the class within another class.
Both concept can be applied to implement funtionality in a program or an application, depends on the purpose of the functionality, if you want a class to control another classes object and it's lifetime, composition is the choice, or you just want refer an object use aggregation. 😊