Method overriding occurs when a subclass provides a specific implementation of a method that is already defined in its super-class. The method in the subclass overrides the method in the super-class. In Python, for method overriding simply define a method with the same name and signature in the subclass, which will override the method in the parent class.
Method Overriding in Python
In Python, method overriding is a concept where a subclass provides a specific implementation of a method that is already defined in its super-class. The overridden method in the subclass replaces the behavior of the parent class’s method. There are different techniques to implement method overriding in Python, along with variations to customize the behavior.
- Basic Method Overriding – Redefine a method in the subclass.
- Using
super()
– Extend the parent class’s method in the subclass. - Overriding Constructors (
__init__
) – Redefine constructors withsuper()
. - Overriding Class Methods – Override class methods using
@classmethod
. - Overriding Static Methods – Override static methods using
@staticmethod
. - Overriding Properties – Customize or extend properties using
@property
. - Overriding Magic Methods – Override special dunder methods (e.g.,
__str__
,__eq__
). - Multiple Inheritance Overriding – Override methods in classes with multiple inheritance.
- Using
super()
in MRO – Handle method calls based on the Method Resolution Order (MRO) in multiple inheritance. - Overriding Private Methods – Technically possible, but involves name mangling.
Basic Method Overriding
For basic method overriding, we define a method in the subclass with the same name and signature as a method in the parent class. The subclass’s method overrides the parent class’s method when called on an instance of the subclass.
# Basic Method Overriding
# Parent class
class Course:
def course_details(self):
raise NotImplementedError("Subclasses must implement this method")
# Child class 1
class PythonCourse(Course): # Inherits from Course
def course_details(self): # override definition of course_details function from Course class
print("Course: Python Programming\nDuration: 8 Weeks")
# Child class 2
class PowerBICourse(Course): # Inherits from Course
def course_details(self): # override definition of course_details function from Course class
print("Course: Power BI for Data Analysis\nDuration: 6 Weeks")
python_course = PythonCourse()
powerbi_course = PowerBICourse()
python_course.course_details() # Output => Course: Python Programming\nDuration: 8 Weeks
powerbi_course.course_details() # Output => Course: Power BI for Data Analysis\nDuration: 6 Weeks
In this example, Child classes PythonCourse
and PowerBICourse
inherits the parent class Course
and override its method course_details()
to provide course specific details.
super()
Method Overriding – Using This is another technique for method overriding calling parent class’s method using super()
. We can call the overridden method from the parent class using the super()
function within the subclass method. This allows us to extend the parent class’s functionality.
# Method Overriding - Using super()
# Parent class
class Course:
def course_details(self):
return "Course completion certification"
# Child class 1
class PythonCourse(Course): # Inherits from Course
def course_details(self): # override definition of course_details function from Course class
# Call the parent class's method using super()
parent_course_details = super().course_details()
return "Course: Python Programming\nDuration: 8 Weeks\n" + parent_course_details
# Child class 2
class PowerBICourse(Course): # Inherits from Course
def course_details(self): # override definition of course_details function from Course class
# Call the parent class's method using super()
parent_course_details = super().course_details()
return "Course: Power BI for Data Analysis\nDuration: 6 Weeks\n" + parent_course_details
python_course = PythonCourse()
powerbi_course = PowerBICourse()
print(python_course.course_details())
# Output => Course: Python Programming\nDuration: 8 Weeks\nCourse completion certification
print(powerbi_course.course_details())
# Output => Course: Power BI for Data Analysis\nDuration: 6 Weeks\nCourse completion certification
In this example, Child classes PythonCourse
and PowerBICourse
inherits the parent class Course
and override its method course_details()
to provide course specific details. course_details()
method in child classes calls the parent class method using super().course_details()
and add the generic details in each course.
__init__
)
Method Overriding – Using Constructors (We can override constructors in subclasses by redefining the __init__
method. It’s common to use super().__init__()
to inherit and extend the parent class constructor.
# Method Overriding - Using Constructors (__init__)
# Parent class
class Course:
def __init__(self, name, duration): # parent class constructor
self.name = name
self.duration = duration
# Child class 1
class PythonCourse(Course): # Inherits from Course
def __init__(self, name, duration):
super().__init__(name, duration) # call the parent class's constructor
self.course_syllabus = "Python course syllabus" # sets another attribute
def course_details(self): # method to get complete course details
return f"{self.name}, {self.duration}, {self.course_syllabus}"
python_course = PythonCourse("Python Programming", "Duration: 8 Weeks")
print(python_course.course_details())
# Output => Python Programming, Duration: 8 Weeks, Python course syllabus
In this example, Child classe PythonCourse
inherits the parent class Course
. __init__
method in child classes calls the parent class method using super().__init__()
and sets the common attribute values for each course. Using the course_details()
method we got all the attribute values of the course.
@classmethod
Method Overriding – Using In previous sections, we have seen the method overriding for class method which were called using the class objects or class instances. e.g we called python_course.course_details()
using the PythonCourse class object.
Similar to that, class methods can also be overridden. Class methods are defined using the @classmethod
decorator and cls
as the first parameter.
# Method Overriding - Using @classmethod
# Parent class
class Course:
@classmethod # Convert a function to be a class method.
def course_details(cls): # first parameter as cls
return "Course completion certification"
# Child class 1
class PythonCourse(Course): # Inherits from Course
@classmethod # Convert a function to be a class method.
def course_details(cls): # override course_details function from Course class
return "Course: Python Programming\nDuration: 8 Weeks"
# Child class 2
class PowerBICourse(Course): # Inherits from Course
@classmethod # Convert a function to be a class method.
def course_details(cls): # override course_details function from Course class
return "Course: Power BI for Data Analysis\nDuration: 6 Weeks"
print(PythonCourse.course_details())
# Output => Course: Python Programming\nDuration: 8 Weeks
print(PowerBICourse.course_details())
# Output => Course: Power BI for Data Analysis\nDuration: 6 Weeks
- In this example, Child classes
PythonCourse
andPowerBICourse
inherits the parent classCourse
and override its methodcourse_details()
to provide course specific details. course_details()
method in parent class and child classes is annotated with@classmethod
and first parameter iscls
.- This makes
course_details()
method as class method. It means, to call this method we don’t need to create class object. - We can call
course_details()
method directly using the class likePythonCourse.course_details()
andPowerBICourse.course_details()
.
@staticmethod
Method Overriding – Using Static methods (defined using the @staticmethod
decorator) can also be overridden in sub-classes. These methods don’t rely on instance or class references.
# Method Overriding - Using @staticmethod
# Parent class
class Course:
@staticmethod # Convert a function to static method.
def course_details(): # first parameter as cls
return "Course completion certification"
# Child class 1
class PythonCourse(Course): # Inherits from Course
@staticmethod # Convert a function to static method.
def course_details(): # override course_details function from Course class
return "Course: Python Programming\nDuration: 8 Weeks"
# Child class 2
class PowerBICourse(Course): # Inherits from Course
@staticmethod # Convert a function to static method.
def course_details(): # override course_details function from Course class
return "Course: Power BI for Data Analysis\nDuration: 6 Weeks"
print(PythonCourse.course_details())
# Output => Course: Python Programming\nDuration: 8 Weeks
print(PowerBICourse.course_details())
# Output => Course: Power BI for Data Analysis\nDuration: 6 Weeks
- In this example, Child classes
PythonCourse
andPowerBICourse
inherits the parent classCourse
and override its methodcourse_details()
to provide course specific details. course_details()
method in parent class and child classes is annotated with@staticmethod
@staticmethod
annotation makescourse_details()
method as static method. It means, we can call this method using the class and don’t need class object to call this method.- We can call
course_details()
method directly using the class likePythonCourse.course_details()
andPowerBICourse.course_details()
.
@property
Overriding Properties Using Properties in Python can be overridden using the @property
decorator. Sub-classes can redefine or extend property behavior.
# Overriding Properties Using @property
# Parent class
class Course:
@property # define property
def course_details(self):
return "Course completion certification"
# Child class 1
class PythonCourse(Course): # Inherits from Course
@property # define property
def course_details(self): # override course_details function from Course class
return "Course: Python Programming\nDuration: 8 Weeks\n" + super().course_details
# Child class 2
class PowerBICourse(Course): # Inherits from Course
@property # define property
def course_details(self): # override course_details function from Course class
return "Course: Power BI for Data Analysis\nDuration: 6 Weeks\n" + super().course_details
python_course = PythonCourse()
powerbi_course = PowerBICourse()
print(python_course.course_details)
# Output => Course: Python Programming\nDuration: 8 Weeks\nCourse completion certification
print(powerbi_course.course_details)
# Output => Course: Power BI for Data Analysis\nDuration: 6 Weeks\nCourse completion certification
- In this example, Child classes
PythonCourse
andPowerBICourse
inherits the parent classCourse
and override its propertycourse_details
to provide course specific details. course_details()
function in parent class and child classes is annotated with@property
@property
annotation makescourse_details
as property of the class, which is overridden in child classes.- Child class property is calling the parent class property using
super().course_details
- We can call
course_details
property on the class objects likepython_course.course_details
andpowerbi_course.course_details
.
Overriding Magic (Dunder) Methods
Magic (or “dunder”) methods (e.g., __str__
, __repr__
, __eq__
) can be overridden to customize object behavior.
# Overriding Magic (Dunder) Methods
# Parent class
class Course:
def __str__(self): # define __str__ method
return "Course completion certification"
# Child class 1
class PythonCourse(Course): # Inherits from Course
def __str__(self): # override __str__ method
return "Course: Python Programming\nDuration: 8 Weeks"
course = Course()
python_course = PythonCourse()
print(course) # Output => Course completion certification
print(python_course) # Output => Course: Python Programming\nDuration: 8 Weeks
- In this example, Child class
PythonCourse
inherits the parent classCourse
and override method__str__
. __str__
method is directly called on the class object. We don’t need to specify its method call.__str__
method is called on the class object when we printcourse
andpython_course
.
Method Overriding – Multilevel Inheritance
In multilevel inheritance, class inheritance is in multiple levels. The child class inherits from a parent class, which itself is a child of another class. Ex. Child
class inherits from Parent
class and Parent
class itself inherits from GrandParent
class.
# Method Overriding - Multilevel Inheritance
# GrandParent class
class Shbytes:
def course_info(self): # defined function
print("Generic course info.")
# Parent class (inherits from Shbytes)
class Courses(Shbytes):
def course_info(self): # override function from Shbytes class
print("Courses: Offering a variety of tech and business courses.")
# Child class (inherits from Courses)
class PythonCourse(Courses):
def course_info(self): # override function from Courses class
print("Python Course: A detailed course on Python programming.")
# Creating an object of the grandchild class
python_course = PythonCourse()
python_course.course_info() # Method of PythonCourse (Child class)
# Output => Python Course: A detailed course on Python programming.
- The
Shbytes
class contains a methodcourse_info()
. - The
Courses
class inherits fromShbytes
and override its methodcourse_info()
. - The
PythonCourse
class, which inherits fromCourses
, override methodcourse_info()
. PythonCourse
class has override method fromCourses
class andShbytes
class.
super()
in Multiple Inheritance (MRO)
Method Overriding – Using The Method Resolution Order (MRO) is the order in which Python looks for methods when they are called using super()
. We can check the MRO of any class using the __mro__
attribute or the mro()
method.
ClassName.__mro__
=> Returns tuple of class method resolution orderClassName.mro()
=> Returns list of class method resolution order
# Method Overriding - Using super() in Multiple Inheritance (MRO)
# GrandParent class
class Shbytes:
def course_info(self):
return "courses@shbytes.com"
# Parent class
class Course(Shbytes):
def course_info(self):
return "Course completion certification - " + super().course_info()
# Child class
class PythonCourse(Course): # Inherits from Course
def course_info(self): # override course_details function from Course class
return "Course: Python Programming\nDuration: 8 Weeks\n" + super().course_info()
python_course = PythonCourse()
print(python_course.course_info())
# Output: Course => Python Programming\nDuration: 8 Weeks\nCourse completion certification - courses@shbytes.com
- In this example
PythonCourse
class inheritsCourse
class which inheritsShbytes
class. course_info()
method override from parent class. This method calls the parent class method usingsuper().course_info()
super()
ensures that all classes in a hierarchy are properly initialized and called in the correct order, especially in the case of multiple inheritance.- It avoids to hardcode the parent class, leading to more maintainable and extendable code.
Private Methods Not Overriden
Private methods (methods with a name starting with __
) can be overridden in sub-classes, though it’s less common. Since they are name-mangled, they are overridden by matching the mangled name. Private methods can be tricky to override due to name mangling, and it’s not recommended to rely on this approach heavily.
# Method Overriding - Private Methods
class Course(Shbytes):
def __course_info(self): # define private method for Course class
return "Course completion certification"
def get_course_info(self): # method calling private method
return self.__course_info()
class PythonCourse(Course):
def __course_info(self): # define private method for PythonCourse class
return "Course: Python Programming\nDuration: 8 Weeks"
python_course = PythonCourse()
print(python_course.get_course_info())
# Output: Course completion certification (private method not overridden)
In this example, __course_info
method in PythonCourse
class is trying to override private method from Course
class. But, from the output when we called python_course.get_course_info()
we got the response from the parent method itself. Private method is not overridden.
Summary
In this article, we learned about various techniques for Method Overriding in Python. Following topics were covered:
- Method Overriding in Python
- Basic Method Overriding
- Method Overriding – Using super()
- Method Overriding – Using Constructors (__init__)
- Method Overriding – Using @classmethod
- Method Overriding – Using @staticmethod
- Overriding Properties Using @property
- Overriding Magic (Dunder) Methods
- Method Overriding – Multilevel Inheritance
- Method Overriding – Using super() in Multiple Inheritance (MRO)
- Private Methods Not Overriden
Code – Github Repository
All code snippets and programs for this article and for Python tutorial, can be accessed from Github repository – Comments and Docstring in Python.