Python Inheritance: Subclasses and Parent Classes
Inheritance builds a new class on top of an existing one. The subclass gets every method and attribute of its parent class, and can add its own.
Read Methods and self first.
Create a subclass
Put the parent class in brackets after the new class name.
class Animal:
def __init__(self, name):
self.name = name
def describe(self):
return f"{self.name} is an animal"
class Dog(Animal):
def fetch(self):
return f"{self.name} fetches the ball"
rex = Dog("Rex")
print(rex.describe())
print(rex.fetch())
Dog has no __init__ or describe of its own. It uses the ones from
Animal, and adds fetch.
Check a type with isinstance()
An instance of a subclass also counts as an instance of its parent. The reverse is not true.
class Animal:
def __init__(self, name):
self.name = name
class Dog(Animal):
pass
rex = Dog("Rex")
tom = Animal("Tom")
print(isinstance(rex, Dog))
print(isinstance(rex, Animal))
print(isinstance(tom, Dog))
print(issubclass(Dog, Animal))
isinstance(object, class) asks "is this object that kind of thing?".
issubclass(child, parent) asks the same about two classes.
Share code between subclasses
Put the code every subclass needs in the parent, once. Each subclass adds only what makes it different.
class Vehicle:
def __init__(self, name, wheels):
self.name = name
self.wheels = wheels
def summary(self):
return f"{self.name}: {self.wheels} wheels"
class Bike(Vehicle):
def ring(self):
return "Ring ring!"
class Truck(Vehicle):
def load(self, tonnes):
return f"Carrying {tonnes} tonnes"
for vehicle in [Bike("Bike", 2), Truck("Truck", 6)]:
print(vehicle.summary())
print(Bike("Bike", 2).ring())
The loop calls summary on both, because both inherit it from Vehicle.
Only a Bike has ring.
How Python finds a method
Python looks for a method in the object's own class first. Then it tries the
parent, then the parent's parent. Every class ends at object.
class Animal:
def describe(self):
return "an animal"
class Dog(Animal):
pass
class Puppy(Dog):
pass
print(Puppy().describe())
print([cls.__name__ for cls in Puppy.__mro__])
__mro__ is that search order (the method resolution order). Puppy
and Dog have no describe, so Python uses the one in Animal.
Note: Use inheritance when the subclass really is a kind of the
parent: a Dog is an Animal. When one object only has another, such as
a Car that has an Engine, store it as an attribute instead.
See also: Method overriding and super(), Classes and objects.
Your turn
Add a SavingsAccount class that inherits from Account. Give it an
add_interest() method that adds self.balance // 10 to the balance.
class Account:
def __init__(self, owner):
self.owner = owner
self.balance = 0
def deposit(self, amount):
self.balance += amount
# add three lines: class SavingsAccount(Account) with an add_interest method
savings = SavingsAccount("Mia")
savings.deposit(50)
savings.add_interest()
print(savings.owner, savings.balance)
print(isinstance(savings, Account))
Expected output
Mia 55
True