Python inheritance and polymorphism
Call overridden behavior through a common interface.
Python
class Animal:
def speak(self):
return "sound"
class Dog(Animal):
def speak(self):
return "woof"
class Cat(Animal):
def speak(self):
return "meow"
for animal in [Dog(), Cat()]:
print(animal.speak())Output
woof meow
Explanation
A subclass can inherit behavior and replace a method with its own implementation. Calling the method uses the actual object's implementation.
Polymorphism means the same operation can work with different compatible objects. Python also supports this without inheritance through duck typing: the object needs the required behavior.
Explore the dry run
Guided walkthroughReady
1
class Animal:2
def speak(self):3
return "sound"4
5
class Dog(Animal):6
def speak(self):7
return "woof"8
9
class Cat(Animal):10
def speak(self):11
return "meow"12
13
for animal in [Dog(), Cat()]:14
print(animal.speak())Follow the example
Start to inspect the source, values, and output. These prepared steps explain the published sample; grouped loop steps describe multiple iterations.
View the complete dry-run table
| Step / line | What happens | State after step | Output so far |
|---|---|---|---|
| Construct two subclass instances and visit Dog first. | animal = Dog instance | — | |
| Dispatch speak to Dog.speak. | return = woof | — | |
| Print the first returned sound. | return = woof | woof | |
| Visit the Cat instance next. | animal = Cat instance | woof | |
| Dispatch to Cat.speak. | return = meow | woof | |
| Print the second sound. | return = meow | woof meow |
Cost and common mistakes
O(n) method calls for n animals; O(n) space for the sample list.
- Use inheritance for a meaningful substitutable relationship, not merely to reuse a few lines.
- Changing a method's expected arguments can break callers that rely on a common interface.
Try it yourself
Add Bird with a speak method returning chirp.
Reveal answer and reasoning
Include Bird() in the list. The third line becomes chirp; the loop does not need to change.