Inheritance in Python
Reuse and extend classes with inheritance: single, multilevel and multiple inheritance, super(), and method overriding.
Learning objectives
- βCreate a child class that inherits from a parent class
- βCall the parent's __init__ and methods with super()
- βOverride a method to change its behaviour in a child class
- βRecognise single, multilevel and multiple inheritance, and check relationships with isinstance() and issubclass()
π‘ Key points
- Inheritance lets a new class (child or subclass) reuse the attributes and methods of an existing class (parent or base class).
- Syntax: class Child(Parent): β the parent class goes in the brackets. A child IS-A kind of parent: a Student is a Person.
- super().__init__(...) runs the parent's constructor so the parent's attributes get set up too.
- Overriding: a method in the child with the same name as one in the parent replaces it for child objects.
- Single: one parent. Multilevel: a chain, A β B β C. Multiple: one child with two or more parents, class C(A, B).
- Python looks for a method in the object's own class first, then in its parents from left to right. This search order is the MRO.
- isinstance(obj, Class) and issubclass(Child, Parent) check relationships. Every class ultimately inherits from object.
π» Code examples(6)
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def introduce(self):
print(f"I am {self.name}, {self.age} years old")
class Student(Person): # Student IS-A Person
pass
s = Student("Amit", 16)
s.introduce() # inherited method
print(s.name)
I am Amit, 16 years old Amit
# uses the Person class from example 1
class Student(Person):
def __init__(self, name, age, roll, marks):
super().__init__(name, age) # parent's part
self.roll = roll # Student's part
self.marks = marks
def result(self):
return "Pass" if self.marks >= 33 else "Fail"
s = Student("Priya", 17, 12, 88)
s.introduce()
print(s.roll, s.marks, s.result())
I am Priya, 17 years old 12 88 Pass
# uses the Person class from example 1
class Teacher(Person):
def __init__(self, name, age, subject):
super().__init__(name, age)
self.subject = subject
def introduce(self): # overrides
super().introduce() # parent's version
print(f"I teach {self.subject}")
people = [Person("Ravi", 15),
Teacher("Mrs. Sharma", 42, "Physics")]
for p in people:
p.introduce()
I am Ravi, 15 years old I am Mrs. Sharma, 42 years old I teach Physics
class Animal:
def __init__(self, name):
self.name = name
def breathe(self):
return f"{self.name} breathes"
class Mammal(Animal):
def feed(self):
return f"{self.name} drinks milk as a baby"
class Dog(Mammal):
def sound(self):
return f"{self.name} says Woof"
d = Dog("Moti")
print(d.breathe()) # from Animal
print(d.feed()) # from Mammal
print(d.sound()) # its own
print(isinstance(d, Animal), issubclass(Dog, Mammal))
Moti breathes Moti drinks milk as a baby Moti says Woof True True
class Father:
def drive(self):
return "can drive"
def hobby(self):
return "gardening"
class Mother:
def cook(self):
return "can cook"
def hobby(self):
return "painting"
class Child(Father, Mother):
pass
c = Child()
print(c.drive(), "and", c.cook())
print(c.hobby()) # Father is listed first
print([k.__name__ for k in Child.__mro__])
can drive and can cook gardening ['Child', 'Father', 'Mother', 'object']
class Account:
def __init__(self, holder, balance=0):
self.holder = holder
self.balance = balance
def withdraw(self, amt):
if amt > self.balance:
print("Insufficient balance")
else:
self.balance -= amt
print(f"Withdrew βΉ{amt}, left βΉ{self.balance}")
class SavingsAccount(Account):
MIN_BALANCE = 500
def withdraw(self, amt):
if self.balance - amt < self.MIN_BALANCE:
print(f"Must keep βΉ{self.MIN_BALANCE}")
else:
super().withdraw(amt)
def __str__(self):
return f"{self.holder}: βΉ{self.balance}"
s = SavingsAccount("Amit", 2000)
s.withdraw(1200)
s.withdraw(400)
print(s)
Withdrew βΉ1200, left βΉ800 Must keep βΉ500 Amit: βΉ800
π― Practice
Q1. What is printed? class A: def show(self): print('A') class B(A): def show(self): print('B') B().show()+
B. B overrides show(), so its own version runs.
Q2. What does super().__init__(name) do inside a child class's __init__?+
It calls the parent class's __init__, so the parent's attributes (here, name) are set up on the new object.
Q3. class A: ..., class B(A): ..., class C(B): ... β which type of inheritance is this?+
Multilevel inheritance: C inherits from B, which inherits from A.
Q4. In class C(A, B), both A and B define greet(). Which one does C().greet() run?+
A's greet(). Python searches the parents from left to right, and A is listed first.
Q5. Using the Rectangle class from Day 10, write a Square class that only needs one side length.+
class Square(Rectangle): def __init__(self, side): super().__init__(side, side) print(Square(4).area()) # 16
π Notes
Types of inheritance
Single Multilevel Multiple Hierarchical
A A A B A
| | \ / / \
B B C B C
|
C
- Single:
class B(A) - Multilevel:
class B(A)andclass C(B) - Multiple:
class C(A, B) - Hierarchical: several children of one parent, such as
Student(Person)andTeacher(Person)in today's examples
Overriding is not overloading
Some languages let you write two methods with the same name but different parameters (overloading). Python does not: if a class defines the same method name twice, the last definition simply replaces the first. Use default arguments (Day 9) instead.
Checking what an object is
t = Teacher("Mrs. Sharma", 42, "Physics")
print(isinstance(t, Teacher)) # True
print(isinstance(t, Person)) # True
print(issubclass(Person, Teacher)) # False
A Teacher is a Person, but a Person is not necessarily a Teacher.
Common mistakes
- Forgetting super().init(): if the child defines its own
__init__without calling the parent's, attributes likeself.nameare never created, and using them raises AttributeError: 'Student' object has no attribute 'name'. - Passing self to super(): write
super().__init__(name), notsuper().__init__(self, name). - Misspelling an overriding method:
def introduse(self)adds a new method; the parent'sintroduce()still runs. - Using inheritance for "has-a" relationships: a Car has an Engine, it is not a kind of Engine. Store an Engine object as an attribute instead.
Next: practise days 11β20 together by building a small student record system that uses classes, a dictionary, exception handling and a CSV file.