Inheritance
Part of the free LogicWiz Python course, Module 9: Object-oriented programming. The examples and practice run in the app.
The canteen now sells drinks (with a size) and combo meals (with a discount). Aarav copy-pasted the Item class twice, then found a bug and had to fix it in three places. Inheritance writes the shared part once.
You'll learn to
- Make a child class that reuses and overrides a parent
- Call the parent with `super()`
- Recognise single, multilevel, hierarchical and multiple inheritance
- Read the MRO and solve the diamond problem
Learn
A Drink *is an* Item
class Drink(Item): makes Drink a child (subclass) of Item, the parent (base class). A drink gets everything an item has, its attributes and methods, for free.
The child can then add new things (a size) and override a method by defining one with the same name. Use inheritance when the sentence "a Drink is an Item" sounds right.
Reuse, extend, override
class Item:
def __init__(self, name, price):
self.name = name
self.price = price
def label(self):
return f"{self.name}: Rs {self.price}"
class Drink(Item):
def __init__(self, name, price, size):
super().__init__(name, price) # let Item set name and price
self.size = size
def label(self): # override, but reuse the parent's
return super().label() + f" ({self.size})"
c = Drink("Cold coffee", 60, "large")
print(c.label())
print(isinstance(c, Item), issubclass(Drink, Item))
Types of inheritance
| Type | Shape and example |
|---|---|
| Single | A → B: Item → Drink |
| Multilevel | A → B → C: Person → Student → Topper |
| Hierarchical | One parent, many children: Person → Student, Person → Teacher |
| Multiple | One child, many parents: class TA(Student, Teacher) |
| Hybrid | A mix of the above, e.g. the diamond below |
Multilevel and hierarchical
class Person:
def __init__(self, name):
self.name = name
def role(self):
return "person"
class Student(Person): # single
def role(self):
return "student"
class Topper(Student): # multilevel: Person -> Student -> Topper
def role(self):
return "topper, and a " + super().role()
class Teacher(Person): # hierarchical: Person has two children
pass
for p in [Student("Riya"), Topper("Aarav"), Teacher("Mrs Iyer")]:
print(p.name, "-", p.role())
Teacher defines nothing, so it uses Person.__init__ and Person.role.
Multiple inheritance and the diamond
class D(B, C) has two parents. If both B and C come from A, the classes form a diamond. When you call D().hello(), which version runs?
Python answers with the MRO (method resolution order), worked out by the C3 algorithm: the child first, then the parents left to right, and every class appears once, always before its own parents. See it with D.mro() or D.__mro__.
Reading the MRO
class A:
def hello(self):
return "A"
class B(A):
def hello(self):
return "B"
class C(A):
def hello(self):
return "C"
class D(B, C):
pass
print(D().hello())
print([k.__name__ for k in D.mro()])
Swap to class D(C, B) and run again: now C comes first.
super() means "the next class in the MRO", not "my parent". In a diamond, super() inside B can call C, a class B knows nothing about. That's what lets every class in the diamond run exactly once. And if a child defines __init__ but forgets super().__init__(...), the parent's attributes are never set, and you get AttributeError later.
Semester papers ask "Explain the types of inheritance with an example of each": draw the arrow shapes from the table and write a 3-line class pair for each. Interviews ask "What is MRO? What is the diamond problem and how does Python solve it?": answer with C3 linearisation and ClassName.mro().
In one line
class Child(Parent) reuses and overrides; super() calls the next class in the MRO; check the order with Cls.mro().
Interview corner
What types of inheritance does Python support?
Single (A → B), multilevel (A → B → C), hierarchical (one parent, many children), multiple (one child, many parents) and hybrid (a mix). Python supports all of them, including multiple inheritance, which Java does not support for classes.
What is the MRO, and how does Python solve the diamond problem?
The Method Resolution Order is the order Python searches classes for an attribute. Python computes it with C3 linearisation: a child before its parents, parents left to right, each class once. In class D(B, C) with both from A, the MRO is D, B, C, A, object, so A is reached only once. Inspect it with D.mro() or D.__mro__.
What does `super()` do?
super() returns a proxy that finds the next class in the instance's MRO after the current one. With single inheritance that's the parent; with multiple inheritance it may be a sibling. This is how cooperative __init__ chains call every class once. Calling Parent.__init__(self) directly skips this and can run a class twice in a diamond.
What is method overriding?
A subclass defines a method with the same name as the parent, replacing it for subclass objects. The overriding method can still reuse the parent version with super().method(). Overriding is the basis of runtime polymorphism.