Inheritance and Composition in Python
In object-oriented programming (OOP), Inheritance and Composition are two fundamental concepts used to establish relationships between classes. These concepts help in reusing code and building complex systems efficiently.
What is Inheritance?
Inheritance allows a class (called a child class or subclass) to inherit attributes and methods from another class (called a parent class or superclass). This enables code reusability and establishes an “is-a” relationship between classes.
Syntax
class ParentClass:
# Parent class methods and attributes
class ChildClass(ParentClass):
# Child class can access methods and attributes of ParentClass
Examples of Inheritance
1. Basic Inheritance Example
In this example, we define a Parent
class and a Child
class that inherits from it.
When the child class inherits from the parent class, it automatically gets access to the parent’s methods and attributes without redefining them.
class Animal:
def speak(self):
print("Animal speaks")
class Dog(Animal): # Dog class inherits from Animal class
def bark(self):
print("Dog barks")
# Creating an object of the Dog class
dog = Dog()
dog.speak() # Inherited method
dog.bark() # Method of Dog class
Output:
Animal speaks
Dog barks
Here, the Dog
class inherits the speak()
method from the Animal
class and also defines its own method, bark()
.
2. Method Overriding in Inheritance
Sometimes, a child class may need to provide its own version of a method inherited from the parent class. This is called method overriding.
class Animal:
def speak(self):
print("Animal makes a sound")
class Cat(Animal):
def speak(self): # Overriding the parent class method
print("Cat meows")
# Creating an object of Cat
cat = Cat()
cat.speak() # Calls the overridden method in the Cat class
Output:
Cat meows
Here, the Cat
class overrides the speak()
method from the Animal
class to provide its own behavior.
What is Composition?
Composition is another way to reuse code in OOP. Instead of inheriting from another class, one class contains an instance of another class as an attribute. This establishes a “has-a” relationship rather than an “is-a” relationship.
Syntax
class ClassA:
# Methods and attributes
class ClassB:
def __init__(self):
self.object_a = ClassA() # Creating an instance of ClassA inside ClassB
Examples of Composition
1. Basic Composition Example
Here, we define a Engine
class and a Car
class that contains an instance of Engine
.
class Engine:
def start(self):
print("Engine starts")
class Car:
def __init__(self):
self.engine = Engine() # Composition: Car has an Engine
def drive(self):
print("Car is driving")
self.engine.start() # Using the Engine's start method
# Creating an object of Car
car = Car()
car.drive()
Output:
Car is driving
Engine starts
Here, the Car
class does not inherit from Engine
. Instead, it contains an Engine
instance, meaning Car
“has an” Engine
. This allows us to reuse the functionality of the Engine
class inside the Car
class.
Difference Between Inheritance and Composition
Feature | Inheritance | Composition |
---|---|---|
Relationship Type | “is-a” | “has-a” |
Code Reuse | Code is reused by extending parent class | Code is reused by including instances of other classes |
Flexibility | Less flexible; changing the parent class affects all child classes | More flexible; changes in one class do not affect others |
Complexity | Can become complex due to deep inheritance hierarchies | More modular and maintainable |
Both inheritance and composition are useful in different scenarios. Inheritance is ideal when a subclass truly extends the functionality of a parent class, whereas composition is preferred when different classes work together without tightly coupling them.