22.4. Invoking the Parent Class’s Method¶
Sometimes the parent class has a useful method, but you just need to execute a little extra code when running the subclass’s method. You can override the parent class’s method in the subclass’s method with the same name, but also invoke the parent class’s method. Here’s how.
Say you wanted the Dog
subclass of Pet
to say “Arf! Thanks!” when the feed
method is called, as well as executing the code in the original method.
Here’s the original Pet
class again.
And here’s a subclass that overrides feed()
by invoking the the parent class’s feed()
method; it then also executes an extra line of code. It does this by calling the built-in function super()
. The super()
function returns a special object that allows you to invoke the method of the parent class. So to call the parent class’s feed()
method (Pet.feed()
), we say super().feed()
.
Note
Another way to invoke the parent’s method is to explicitly refer to the parent class’ method and invoke it on the instance. So, in this case, we could say Pet.feed(self)
. This is a little more explicit, but it’s also a little less flexible. If we later change the name of the parent class, we’d have to change it in all the subclasses. Also, if we later change the class hierarchy, so that Dog
is a subclass of some other class, we’d have to change the code in all the subclasses. So, it’s better to use super()
.
This technique is very often used with the __init__
method for a subclass. Suppose that some extra instance variables are defined for the subclass. When you invoke the constructor, you pass all the regular parameters for the parent class, plus the extra ones for the subclass. The subclass’ __init__
method then stores the extra parameters in instance variables and calls the parent class’ __init__
method to store the common parameters in instance variables and do any other initialization that it normally does.
Let’s say we want to create a subclass of Pet
, called Bird
, and we want it to take an extra parameter, chirp_number
, with a default value of 2
, and have an extra instance variable, self.chirp_number
. Then, we’ll use this in the hi
method to make more than one sound.
Check your understanding
- 7
- This would print if the code was print(b2.chirp_number).
- ["Mrrp"]
- We set b2 to be Bird('Sunny', 7) above. Bird is a subclass of Pet, which has ["Mrrp"] for sounds, but Bird has a different value for that class variable. The interpreter looks in the subclass first.
- ["chirp"]
- The interpeter finds the value in the class variable for the class Bird.
- Error
- We ran set b2 to be Bird('Sunny', 7) above. Bird has a value set for the attribute sounds.
What will the following code print (assuming we use the above definitions of Bird
and Pet
):
b2 = Bird('Sunny', 7)
print(b2.sounds)
- Error when invoked
- Since we are no longer calling the parent method in the subclass method definition, the actions defined in the parent method feed will not happen, and only Arf! Thanks! will be printed.
- The string "Arf! Thanks!" would not print out but d1 would still have its hunger reduced.
- Remember that the Python interpreter checks for the existence of feed in the Dog class and looks for feed in Pet only if it isn't found in Dog.
- The string "Arf! Thanks!" would still print out but d1 would not have its hunger reduced.
- Since we are no longer calling the parent Pet class's method in the Dog subclass's method definition, the class definition will override the parent method.
- Nothing would be different. It is the same as the current code.
- Remember that the Python interpreter checks for the existence of feed in the Dog class and looks for feed in Pet only if it isn't found in Dog.
For the Dog
class defined in the earlier activecode window, what would happen when d1.feed()
is run if the super().feed()
line was deleted?