Inheritance / super() / Multiple Inheritance
In Python, you inherit a class using the syntax class ChildClass(ParentClass). A child class inherits the methods and properties of its parent class and can override them as needed. super() is used to call a method defined in the parent class. Python supports multiple inheritance, which lets you define a class with more than one parent class, but this can make the design more complex and should be used with care.
Syntax
# Inheritance
class ChildClass(ParentClass):
def __init__(self, ...):
super().__init__(...) # Call the parent __init__
# Method override
def method(self):
super().method() # Also call the parent method if needed
# Additional logic
# Multiple inheritance
class ChildClass(Parent1, Parent2):
pass
Syntax / Function Reference
| Syntax / Function | Description |
|---|---|
| class Child(Parent) | Defines a child class that inherits from a parent class. |
| super() | Returns a proxy object that refers to the parent class (or the next class in the MRO). |
| super().__init__() | Calls the initialization method of the parent class. |
| class Child(Parent1, Parent2) | Defines a class that inherits from multiple parent classes. |
| Class.__mro__ | An attribute that returns the MRO (Method Resolution Order) as a tuple. |
Sample Code
# Basic inheritance
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
return f"{self.name} is making a sound"
def __str__(self):
return f"{self.__class__.__name__}({self.name})"
class Dog(Animal):
def __init__(self, name, breed):
super().__init__(name) # Call the parent __init__
self.breed = breed # Attribute specific to the child class
def speak(self): # Override the parent method
return f"{self.name} says Woof!"
def fetch(self): # Method specific to the child class
return f"{self.name} fetched the ball!"
class Cat(Animal):
def speak(self):
return f"{self.name} says Meow!"
d = Dog('Buddy', 'Shiba Inu')
c = Cat('Whiskers')
print(d.speak()) # Buddy says Woof!
print(c.speak()) # Whiskers says Meow!
print(d.fetch()) # Buddy fetched the ball!
print(d.breed) # Shiba Inu
# Check inheritance relationships with isinstance
print(isinstance(d, Dog)) # True
print(isinstance(d, Animal)) # True (Dog inherits from Animal)
# Override a method while still calling the parent version via super()
class GuideDog(Dog):
def speak(self):
base = super().speak() # Call Dog's speak
return f"{base} (guide dog)"
gd = GuideDog('Lab', 'Labrador')
print(gd.speak()) # Lab says Woof! (guide dog)
# Multiple inheritance and MRO (C3 linearization algorithm)
class Flyable:
def move(self):
return "Flying"
class Swimmable:
def move(self):
return "Swimming"
class Duck(Flyable, Swimmable):
pass
duck = Duck()
print(duck.move()) # Flying (Flyable is resolved first)
print(Duck.__mro__) # Check the MRO order
# (<class 'Duck'>, <class 'Flyable'>, <class 'Swimmable'>, <class 'object'>)
Notes
The MRO (Method Resolution Order) determines the order in which Python searches for a method. Python resolves the inheritance tree using the C3 linearization algorithm. You can inspect it with Class.__mro__, which shows which class's method takes priority in a multiple inheritance scenario.
When you define __init__() in a child class, you should generally call the parent's __init__() via super(). If you skip this call, the parent class is not initialized, its instance variables are never set, and calling any parent method that relies on them will raise an error.
Multiple inheritance increases code complexity. Where possible, the "composition over inheritance" pattern (delegation instead of subclassing) is recommended as an alternative. Using a class purely as a Mixin — a parent class that adds a specific, self-contained feature — is a case where multiple inheritance is genuinely useful.
If you find any errors or copyright issues, please contact us.