Overriding is when a child class creates a new implementation of an inherited method. When a child class method is created with the same name and signature as one in the parent, the child’s method takes precedence.
You’ve used the concept of overriding a few times in the last two chapters, for example, the ContactSystem:
Each of the children implements its own Send(message) method that behaves differently - sending a text, an email, or to the printer.
And you just do this by writing another method in the child?
It’s as simple as that! Let’s look at this example:
from abc import ABCclass Shape(ABC):def area(self):return 0class Square(Shape):def __init__(self, length):self.length = lengthdef area(self):return length * length
In this example, Shape contains an area method that returns the area of the shape. Square overrides this method by implementing the formula for the area of a square.
So I get that area() is overridden, but how can Shape be a class? What’s
ABC stands for abstract base class. It’s Python’s mechanism for implementing what’s known as an abstract class.
An abstract class can’t be instantiated - the only way to use it is to create a subclass. For example, in the case of Shape - what would it mean to have a Shape object? What would it even look like? You could make Square a subclass of Shape and then use Square. This approach would let you have a typical parent class for Circle, Square, Triangle, etc. without letting anyone instantiate a Shape.
Access Parent Methods
While overriding allows you to entirely change inherited behavior, it’s sometimes useful to be able to access the parent’s methods - the ones that have been overridden.
One of the most common places to use this is in constructors. You do it using super() - like this:
class Sprite:def __init__(self, image):this.image = imagedef render(self):passclass MovingSprite(Sprite):def __init__(self, image, speed):this.speed = speedsuper().__init__(image)def move(self):pass
In this example, MovingSprite is a subclass of Sprite, which moves an image rather than just rendering it in one place. All of the setup for the image and rendering part of the Sprite is done in the Sprite’s constructor, so MovingSprite calls the constructor after it’s done handling the
Couldn’t we just set
this.image = image in MovingSprite’s constructor instead?
You could, but that solution doesn’t scale. Imagine if Sprite’s constructor did other operations to the image (like calculating its height and width) or imagine if MovingSprite got subclassed even further.
The super() approach allows you to reuse code rather than copying it, and ensures that functionality is grouped logically - two of the main benefits of object-oriented programming!
Your Turn: Use Overriding
In this exercise, you’ll be adding overriding to the code used in the last chapter.
Firstly, though, can you think of any classes that should be abstract in your hierarchy? If so, turn them into abstract classes.
Override the display method of FilePost (or your equivalent) to display its corresponding File at the bottom of the post. Then, override the display method of your Image class to print the image’s name and alt text.
Practice Makes Perfect
Complete the following challenge to reinforce your new skills! 🌴🐅
You are not signed in
Sign in to access coding exercises and test your new skills.
It’s possible for a child class to provide its own implementation for something it inherited from its parent.
The child’s implementation takes priority over the parent’s - it overrides the parent’s implementation.
You can use the super method to access methods in the parent class you’ve overridden.
An abstract class is a class that can’t be instantiated - it must be inherited from instead.
In the next chapter, we’ll be looking at different ways of using inheritance: inheritance hierarchies and multiple inheritance.