Inheritance In Python, Understanding Differenent Types. What is MRO in Inheritance

Understand Inheritance In Python
iheritance in python

What is inheritance in programming?

Inheritance is a fundamental concept in object-oriented programming (OOP) that allows a class to inherit properties and behaviors (methods and attributes) from another class. Also, there are some main terms associated with this inheritance concept like Parent Class or Base Class or Superclass (The class whose properties and methods are inherited) and Childclass or Derived Class or Subclass (The class that inherits from the parent class). Here we will discuss inheritance in Python.

Why use inheritance?

  • Code Reusability: Common logic can be written once in the parent class and reused by child classes.
  • Extensibility: You can extend or override functionalities in child classes.
  • Organization: Helps organize and manage complex code hierarchically.
For Example:
class Animal:  # Parent class
    def speak(self):
        return "I make a sound"

class Dog(Animal):  # Child class
    def speak(self):
        return "Woof!"

class Cat(Animal):  # Another child class
    def speak(self):
        return "Meow!"

Here, Animal is the base class with a generic speak() method. Dog and Cat inherit from Animal, but override the speak() method with their specific sounds.

Types Of Inheritance In Python

  1. Single Inheritance: One child class inherits from one parent class.
  2. Multiple Inheritance: A class inherits from multiple parent classes.
  3. Multilevel Inheritance: A class inherits from a class, which in turn inherits from another class.
  4. Hierarchical Inheritance: Multiple classes inherit from the same parent class.
  5. Hybrid Inheritance: A combination of two or more types of inheritance

1. Single Inheritance

class Parent:
    def __init__(self):
        self.parent_attr = "I'm the parent"
    
    def parent_method(self):
        print("Parent method")

class Child(Parent):  # Single inheritance
    def __init__(self):
        super().__init__()
        self.child_attr = "I'm the child"
    
    def child_method(self):
        print("Child method")

# Usage
child = Child()
child.parent_method()  # Inherited from Parent
child.child_method()   # Defined in Child
print(child.parent_attr)  # Inherited attribute

A child class inherits from a single parent class.

2. Multiple Inheritance

class Father:
    def father_method(self):
        print("Father's method")

class Mother:
    def mother_method(self):
        print("Mother's method")

class Child(Father, Mother):  # Multiple inheritance
    def child_method(self):
        print("Child's method")

# Usage
child = Child()
child.father_method()  # From Father
child.mother_method()  # From Mother
child.child_method()   # From Child

A child class inherits from multiple parent classes.

3. Multilevel Inheritance

class Grandparent:
    def grandparent_method(self):
        print("Grandparent's method")

class Parent(Grandparent):
    def parent_method(self):
        print("Parent's method")

class Child(Parent):  # Multilevel inheritance
    def child_method(self):
        print("Child's method")

# Usage
child = Child()
child.grandparent_method()  # From Grandparent
child.parent_method()       # From Parent
child.child_method()        # From Child

A chain of inheritance where a child class becomes a parent for another class.

4. Hierarchical Inheritance

class Animal:
    def eat(self):
        print("Eating...")

class Dog(Animal):  # Hierarchical inheritance
    def bark(self):
        print("Barking...")

class Cat(Animal):  # Hierarchical inheritance
    def meow(self):
        print("Meowing...")

# Usage
dog = Dog()
dog.eat()   # From Animal
dog.bark()  # From Dog

cat = Cat()
cat.eat()   # From Animal
cat.meow()  # From Cat

Multiple child classes inherit from a single parent class.

5. Hybrid Inheritance

class A:
    def method_a(self):
        print("Method A")

class B(A):
    def method_b(self):
        print("Method B")

class C(A):
    def method_c(self):
        print("Method C")

class D(B, C):  # Hybrid inheritance
    def method_d(self):
        print("Method D")

# Usage
d = D()
d.method_a()  # From A
d.method_b()  # From B
d.method_c()  # From C
d.method_d()  # From D

A combination of multiple inheritance types. (hierarchical + multiple)

What is Method Resolytion Order (MRO)?

Python uses C3 linearization to determine the method resolution order in multiple inheritance. This shows the order in which Python will search for methods when they’re called on an instance of class D. Don’t worry if you didn’t get it, let me explain it clearly.

Imagine you have a family where a child inherits traits from multiple parents, grandparents, etc. Now, if both parents have the same trait (like a “speak” method), which one should the child use?

Imagine you have a family where a child inherits traits from multiple parents, grandparents, etc. Now, if both parents have the same trait (like a “speak” method), which one should the child use?

MRO (Method Resolution Order) is Python’s way of deciding which parent class’s method to call first when there’s a conflict in inheritance.

How MRO Works?

Python follows C3 Linearization, a rule-based system to decide the order in which classes are checked when calling a method.

class A:
    def greet(self):
        print("Hello from A")

class B(A):
    def greet(self):
        print("Hello from B")

class C(A):
    def greet(self):
        print("Hello from C")

class D(B, C):
    pass

d = D()
d.greet()  # Which greet() is called?

Question: Should D use B’s greet() or C’s greet()?

MRO Rule: Left to Right, Depth First (but with a twist)

  1. Left Parent First: In class D(B, C)B is checked before C.
  2. If B has parents, check them before moving to C.
  3. No class should appear before its parents.

MRO for DD → B → C → A → object

  • Python checks in this order when calling d.greet().
  • Since B comes first, B.greet() is called.

How to Check MRO?

Use .__mro__ or help(class):

print(D.__mro__)
# Output: (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)

I hope you find this blog helpful. If so then please share this post with your circle. Your support will encourage us to write more such blogs in future. Thank you see you in my next blog.

Leave a Reply

Your email address will not be published. Required fields are marked *