Overriding methods
A derived class can also change a method it inherits. Write a method with the same name in the derived class, and objects of that class use the new version instead. This is called overriding the method.
Say knights wear armor that stops half of every hit:
class Character:
def __init__(self, name, health):
self.name = name
self.health = health
def take_damage(self, amount):
self.health -= amount
def __str__(self):
return f"{self.name} ({self.health} health)"
class Knight(Character):
def take_damage(self, amount):
# The armor stops half of every hit.
self.health -= amount // 2
bram = Knight("Bram", 50)
pip = Character("Pip", 50)
bram.take_damage(20)
pip.take_damage(20)
print(bram)
print(pip)
Bram (40 health)
Pip (30 health)When you call a method, Python first looks for it in the object's own class, and only if it isn't there, in the base class. bram is a Knight, and Knight has its own take_damage, so that's the one that runs. pip is a plain Character, so the original runs. __str__ isn't overridden, so both use the one in Character. It's a method like any other, though: a derived class can override __str__ too.
The base class calls the new version
Overriding reaches further than the calls you write yourself. When a method of the base class calls self.something(), and the object belongs to a derived class that overrides something, the overriding version runs:
class Greeter:
def greeting(self, name):
return f"Hello, {name}."
def greet_all(self, names):
for name in names:
print(self.greeting(name))
class PirateGreeter(Greeter):
def greeting(self, name):
return f"Ahoy, {name}!"
friendly = Greeter()
pirate = PirateGreeter()
friendly.greet_all(["Ada", "Linus"])
pirate.greet_all(["Ada", "Linus"])
Hello, Ada.
Hello, Linus.
Ahoy, Ada!
Ahoy, Linus!greet_all is written only once, in Greeter. When it runs for pirate, self is the pirate greeter, so self.greeting(name) finds the pirate's version. This is a handy way to design classes: the base class does the general work and leaves one small method for each derived class to do in its own way.
Get the name exactly right
An overriding method must have exactly the same name as the method it replaces. If you misspell it, Python doesn't complain: it just adds a new method that nobody calls, and the old one keeps running. When an override seems to be ignored, check the spelling first.