In Python, objects are instances of classes, and these objects can have various types of relationships with one another. Understanding these relationships is crucial for designing efficient and maintainable software. This article explores different kinds of object relationships in python, including inheritance, composition, aggregation and association.
Inheritance
Inheritance allows a class to inherit attributes and methods from another class. The class that inherits is called the sub-class (or derived class), and the class being inherited from is known as the super-class (or base class). This relationship enables code reuse and the creation of specialized versions of general classes.
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
pass
class Dog(Animal):
def speak(self):
return "Woof!"
class Cat(Animal):
def speak(self):
return "Meow!"
In this example, Dog and Cat are sub-classes of Animal. They inherit the name attribute and override the speak method to provide their own implementations.
Composition
Composition is a relationship where a class contains instances of other classes as its members. It's similar to aggregation but implies ownership; if the container class is destroyed, so are its contained objects.
class Engine:
def start(self):
print("Engine started")
class Car:
def __init__(self):
self.engine = Engine()
def start_engine(self):
self.engine.start()
Here, Car has a composition relationship with Engine; it contains an instance of Engine and uses it to perform actions.
Aggregation
Aggregation is a less strict form of composition where the child can exist independently of the parent. Unlike composition, destroying the parent does not necessarily destroy the child.
class Wheel:
def rotate(self):
print("Wheel rotated")
class Vehicle:
def __init__(self):
self.wheel = Wheel()
def move_forward(self):
self.wheel.rotate()
In this case, Vehicle aggregates Wheel, meaning the Wheel can exist without the Vehicle.
Association
Association is a relationship between two classes where one class uses another. It doesn't imply ownership or lifetime dependency.
class Teacher:
def teach(self, student):
print(f"Teaching {student.name}")
class Student:
def __init__(self, name):
self.name = name
teacher = Teacher()
student = Student("Alice")
teacher.teach(student)
Here, Teacher and Student are associated; the Teacher uses the Student to teach.