super()
Overriding parent class methods is very useful. But we don't always discard a parent method and override it with a totally new child method. Most of the time, we'll call a parent method into a child method to make use of it, and override some aspects of the parent method or add on certain functionality on top of it.
super()
function is for this purpose. This built-in Python function allows us to utilize parent class methods even when overriding certain aspects of those methods in our child classes.
It will look like the following:
class MyParentClass():
def __init__(self, x, y):
self.x = x
self.y = y
class SubClass(MyParentClass):
def __init__(self, x, y):
super().__init__(x, y)
# more stuff of its own
See example: Person
and Student
class Person:
def __init__(self, first, last):
self.firstname = first
self.lastname = last
def name(self):
print(self.firstname, self.lastname)
class Student(Person):
def __init__(self, first, last, id):
super().__init__(first, last)
self.studentid = id
def getStudent(self):
super().name()
print("Student ID: " , self.studentid)
Person
is the parent class, it defines a __init__()
and name()
. A Person
object could be:
p = Person('Buzz', 'Coder')
print(p.firstname) # Buzz
p.name() # Buzz Coder
Student
is a sub class of Person
, it's __init__()
overrides the parents':
First, we called __init__
method of the parent class Person
(from the Student
class) using code:
super().__init__(first, last)
We do not need to specify the name of the parent class if we use super(), please note that we used super()
without arguments.
Next, we add another instance variable of it's own: studentid
.
See a Student
object:
s = Student('Elsa', 'King', 1788)
print(s.firstname) # Elsa
print(s.studentid) # 1788
s.name() # Elsa King
s.getStudent() # Elsa King
# Student ID: 1788
You can see that s
as a Student
object, it has instance variables defined in __init__
: firstname, lastname
are defined with calling the parent __init__
, it also has it's own variable studentid
.
s
has method name()
that's inherited from the parent class.
Look at Student
class, it also defines a method getStudent()
, which call in a parent method name()
using code
super().name()
after that it prints out a message about student ID.
So we can see a call on it :
s.getStudent()
The console result is:
Elsa King
Student ID: 1788
Perfect!
===end?
More Exercise:
Pet and _Cat classes
# Pet
class Pet:
def __init__ (self, name, type):
self.name = name
self.type = type
def __str__ (self):
return "%s is a %s." % (self.name, self.type)
# create a Pet object
pet = ('Sniffy', 'hamster')
print(pet) # Sniffy is a hamster.
Next, we are going to define a child class Cat
, it's extended from Pet
.
Cat
has __init__
that defines 3 instance variables: name, type
from the parent, type
has fixed value 'cat'
, and another variable color
of it's own.
Cat
overrides parent method __str__
, it calls the parent __str__
, and will print out more message: It's color is (color).
# Cat is a child class, Pet is the parent class
class Cat( Pet ):
def __init__ (self, name, color):
super().__init__(name, 'cat')
self.color = color
def __str__(self):
return super().__str__() + " It's color is %s." % (self.color)
# make a `Cat` object
sassy = Cat('Sassy', 'yellow')
sassy.type
print(sassy) # Sassy is a cat. It's color is yellow.
??? super().__str__()
did not work??
==
We have overridden the init() method in the Trout child class, providing a different implementation of the init() that is already defined by its parent class Fish. Within the init() method of our Trout class we have explicitly invoked the init() method of the Fish class.
We could have used super instead. super().init(first, last) is automatically replaced by a call to the superclasses method, in this case init:
def __init__(self, first, last, staffnum):
super().__init__(first, last)
self.staffnumber = staffnum
Please note that we used super()
without arguments.
Pet and Cat classes
See another inheritance example for better understanding: Pet
and Cat
classes.
Pet
class is the parent class, it has 4 fields: name, color, type
, and age
.
Cat
is a child class that derived from Pet
class, inherit the 4 fields from Pet
, but they both have some new feature of their own.
So Cat
and Kitten
are all Pet
s. They all inherit the 4 fields from Pet
, but they both have some new feature of their own.
class Pet:
def __init__ (self, n=' ', c=' ', t=' ', a=0):
self.name = n
self.color = c
self.type = t
self.age = a
def setName (self, n ):
self.name = n
def getName (self):
return self.name
def setColor (self, c ):
self.color = c
def getColor (self):
return self.age
def setType (self, t ):
self.type = t
def getType (self):
return self.type
def setAge (self, a)
self.age = a
def getAge (self):
return "{0} years".format(self.age)
def __str__ (self):
return "{0} is a {1} {2} aged {3} years.".format (self.name, self.color, self.type, self.age)
# Cat is a child class, Pet is the parent class
class Cat( Pet ):
def __init__ (self, n=' ', c=' ', a=0):
self.name = n
self.color = c
self.type = 'cat'
self.age = a
def setType (self, t)
print ('{0} refuses to change type, it will always be a {1} in this life.'. format (self.name, self.type) )
def setAge(self, a):
if 1<= a <30:
self.age = a
else:
print("That's not a fit number for a cat's age.")
Pet
class has four things common to all pets: name, color, type
and age
. The code also has setters and getters (accessors). At the end the __str__( )
method can print a simple message about this pet’s name
, age
, type
and color
.
Cat
is subclass of Pet
.
Cat
class constructor accepts only name, color
and age
, it’s type
is fixed to be 'cat'
. The new constructor overrides the Pet
constructor.
Cat
also overrides the setter setType( )
. If someone tries to change the Cat
type, he will not be able to change it, instead he will get a message “…refuses to change type, it will always be a cat in this life!”
.
'Cat' also overrides setAge()
method, it puts a limit on the age
to be 1<age<30 (in years)
.
===
https://www.digitalocean.com/community/tutorials/understanding-inheritance-in-python-3
When we use the super() function, we are calling a parent method into a child method to make use of it. For example, we may want to override one aspect of the parent method with certain functionality, but then call the rest of the original parent method to finish the method.
The built-in Python function super() allows us to utilize parent class methods even when overriding certain aspects of those methods in our child classes.
The init method of our Employee class explicitly invokes the initmethod of the Person class. We could have used super instead. super().init(first, last) is automatically replaced by a call to the superclasses method, in this case init:
def __init__(self, first, last, staffnum):
super().__init__(first, last)
self.staffnumber = staffnum
Please note that we used super()
without arguments.