Composition vs. Inheritance
Imagine you have a toy box with different types of toys. Some toys are cars, and some toys are robots. Now, let’s say you want to create new toys that can be a combination of both cars and robots. There are two main ways to do this: Composition and Inheritance.
Inheritance
Inheritance is like taking a toy car and adding new features to it, like making it fly. You start with something that already exists and builds on top of it.
Example:
Let’s say we have a basic car and we want to create a flying car. We can use inheritance to achieve this.
class Car:
def __init__(self, brand):
self.brand = brand
def drive(self):
return f"The {self.brand} car is driving."
class FlyingCar(Car):
def fly(self):
return f"The {self.brand} car is flying."
# Creating a flying car
my_flying_car = FlyingCar("Tesla")
print(my_flying_car.drive()) # The Tesla car is driving.
print(my_flying_car.fly()) # The Tesla car is flying.
In this example:
- ‘
Car
‘ is the base class (or parent class). - ‘
FlyingCar'
is the derived class (or child class) that inherits from'Car
‘.
Composition
Composition is like having separate toys (a car and a robot) and combining them to make a new toy. Each toy has its own functionalities, and they work together.
Example:
Let’s say we want to create a new toy that can both drive like a car and transform like a robot.
class Car:
def __init__(self, brand):
self.brand = brand
def drive(self):
return f"The {self.brand} car is driving."
class Robot:
def transform(self):
return "The robot is transforming."
class Transformer:
def __init__(self, brand):
self.car = Car(brand)
self.robot = Robot()
def drive(self):
return self.car.drive()
def transform(self):
return self.robot.transform()
# Creating a transformer toy
my_transformer = Transformer("Optimus Prime")
print(my_transformer.drive()) # The Optimus Prime car is driving.
print(my_transformer.transform()) # The robot is transforming.
In this example:
- ‘
Car
‘ and ‘Robot
‘ are separate classes. - ‘
Transformer
‘ uses composition to combine the functionalities of both ‘Car
‘ and ‘Robot
‘.
When to Use Inheritance vs. Composition
- Inheritance: Use it when there is a clear “is-a” relationship. For example, a FlyingCar “is a” Car.
- Composition: Use it when there is a “has-a” relationship. For example, a Transformer “has a” Car and “has a” Robot.
Practice Questions
Question 1
Create a class 'Bird
‘ that has a method ‘fly
‘ that prints “The bird is flying.” Then, create a class ‘SuperBird’ that inherits from ‘Bird’ and adds a new method ‘sing’ that prints “The bird is singing.”
Solution:
class Bird:
def fly(self):
print("The bird is flying.")
class SuperBird(Bird):
def sing(self):
print("The bird is singing.")
# Test the SuperBird
my_super_bird = SuperBird()
my_super_bird.fly() # The bird is flying.
my_super_bird.sing() # The bird is singing.
Question 2
Create two classes, ‘Laptop
‘ and Phone
, each with their own methods (‘code
‘ for Laptop and ‘call
‘ for Phone). Then, create a class ‘SmartDevice
‘ that uses composition to include both ‘Laptop
‘ and 'Phone
‘ functionalities.
Solution:
class Laptop:
def code(self):
print("Coding on the laptop.")
class Phone:
def call(self):
print("Calling on the phone.")
class SmartDevice:
def __init__(self):
self.laptop = Laptop()
self.phone = Phone()
def code(self):
self.laptop.code()
def call(self):
self.phone.call()
# Test the SmartDevice
my_smart_device = SmartDevice()
my_smart_device.code() # Coding on the laptop.
my_smart_device.call() # Calling on the phone.
- Inheritance: Adds new features to an existing class by creating a new class.
- Composition: Combines functionalities from multiple classes into a new class.
By understanding and using inheritance and composition correctly, you can build more flexible and reusable code. Happy coding!