• Composition and Inheritance are OOP concepts that define different ways real-world things can be modelled in computer programs.
  • Inheritance is a mechanism where a new class is derived from an existing class. The new class, called the child or derived class, inherits properties and methods from the parent or base class. (it follows a is-a relationship)
class Animal:
    def speak(self):
        pass
 
class Dog(Animal):
    def speak(self):
        return "Woof!"
  • Composition is a design principle where a class is composed of one or more objects of other classes. Instead of inheriting properties and methods, a class contains instances of other classes that it uses to access their functionality. (it follows a has-a relationship)
class Engine:
    def start(self):
        return "Engine started"
 
class Car:
    def __init__(self):
        self.engine = Engine()
    
    def start_car(self):
        return self.engine.start()
  • Both inheritance and composition have their uses, and the choice between them depends on the specific design requirements of your program.
  • Inheritance is useful for creating hierarchies of related classes, while composition is often more flexible and can lead to more modular designs.

Composition over inheritance

  • Composition is just software building on other software. Composition is much more modular and flexible as it’s much easier to change implementations.
  • Composition allows for behaviours to be altered at runtime by mixing-and-matching different objects whereas behaviour is fixed at compile time in case of inheritance.
  • Composition allows for more complex relationships to be defined whereas inheritance limits the extent of relationships that the objects can have.
  • One side effect is that composition produces looser coupling whereas inheritance leads to tighter coupling between parent and child.