A subclass reuses and specialises its parent. Python supports multiple inheritance and resolves methods with a predictable order — the MRO.
Inheritance & overriding
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
return "..."
def describe(self):
return f"{self.name} says {self.speak()}"
class Dog(Animal):
def __init__(self, name, breed):
super().__init__(name) # let the parent set up its part
self.breed = breed
def speak(self): # override
return "Woof"
d = Dog("Rex", "lab")
print(d.describe()) # Rex says Woof
print(isinstance(d, Animal), issubclass(Dog, Animal)) # True TrueMultiple inheritance & the MRO
class A:
def hello(self): return "A"
class B(A):
def hello(self): return "B→" + super().hello()
class C(A):
def hello(self): return "C→" + super().hello()
class D(B, C):
def hello(self): return "D→" + super().hello()
print(D().hello()) # D→B→C→A
print([k.__name__ for k in D.__mro__]) # ['D', 'B', 'C', 'A', 'object']Abstract base classes
from abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
def area(self) -> float: ...
class Square(Shape):
def __init__(self, side):
self.side = side
def area(self):
return self.side ** 2
print(Square(3).area()) # 9
try:
Shape()
except TypeError:
print("can't instantiate") # can't instantiate