Method Overriding in Python (47/100 Days of Python)
Python allows you to define classes, create objects, and use inheritance to share attributes and methods between classes. One of the key features of inheritance is the ability to override methods in a subclass, which means that you can provide a new implementation of a method in a subclass that replaces or extends the implementation in the parent class. This can be used to customize the behavior of a class to meet the specific needs of your application.
The Basics of Overriding Methods
To override a method in a Python class, you simply create a new method with the same name in the subclass. When you create an instance of the subclass, Python will use the implementation of the method in the subclass, instead of the parent class:
class Shape:
def area(self):
raise NotImplementedError
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14 * (self.radius ** 2)
circle = Circle(10)
print(circle.area()) # Output: 314.0
In this example, we have a parent class Shape
that defines an abstract method area()
. An abstract method is a method that is declared in the parent class, but does not have an implementation. The NotImplementedError
exception is raised to indicate that the method should be overridden in a subclass. There are other ways of defining abstract classes in Python, but for now, we’ll stick to the raise NotImplementedError
implementation.
We then create a subclass Circle
that inherits from Shape
. The Circle
class overrides the area()
method to provide a specific implementation that calculates the area of a circle. When we create an instance of the Circle
class, we pass in the radius of the circle, which is stored as an instance variable.
Finally, we call the area()
method on the circle
object, which returns the area of the circle, as calculated by the implementation in the Circle
class.
Benefits of Overriding Methods
Overriding methods in Python classes provides several benefits, including:
- Customization: You can tailor the behavior of a class to meet the specific needs of your application, without having to modify the original implementation in the parent class.
- Reusability: You can reuse the implementation of a method in a parent class in multiple subclasses, while still allowing for customization when necessary.
- Abstraction: You can define abstract methods in a parent class that provide a general outline of the behavior that should be implemented in subclasses, without having to provide a specific implementation. This allows you to write code that is more flexible and easier to maintain.
Modifying the Constructor
When inheriting from a Python class, you can provide different arguments in the subclass __init__()
function, if necessary. For example, you can add additional arguments to the method in the subclass, or change the number of arguments required by the constructor:
class Shape:
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
raise NotImplementedError
class Rectangle(Shape):
def area(self):
return self.width * self.height
class Square(Rectangle):
def __init__(self, side):
super().__init__(side, side)
square = Square(10)
print(square.area()) # 100
In this example, the Shape
class has a constructor that takes two arguments: width
and height
. The Rectangle
class overrides the area()
method to calculate the area of a rectangle based on the width
and height
attributes.
The Square
class then inherits from Rectangle
, but provides a new constructor that only takes one argument: side
. In the constructor, the width
and height
attributes are set to the value of side
, effectively making the Square
class a special case of the Rectangle
class.
When you create an instance of the Square
class, you pass in the value of side
, and the area()
method returns the area of the square, as calculated by the implementation in the Rectangle
class.
Extending the Functionality
You can also override a method in a Python class to extend its functionality. For example, you can first get the returned value of the base class and then add some more logic to it:
from math import pi
class Shape:
def area(self):
raise NotImplementedError
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return pi * self.radius ** 2
class Cylinder(Circle):
def __init__(self, radius, height):
super().__init__(radius)
self.height = height
def area(self):
base_area = super().area()
return base_area * self.height
cylinder = Cylinder(10, 20)
print(cylinder.area()) # 6283.185307179587
In this example, the Circle
class overrides the area()
method in the Shape
class to return a float value that represents the area of a circle.
The Cylinder
class then inherits from Circle
, and overrides the area()
method to return a float value that represents the total surface area of a cylinder. The base_area
variable is calculated by calling the area()
method on the parent class, using the super()
function.
When you create an instance of the Cylinder
class, you pass in the radius and height of the cylinder, and the area()
method returns the total surface area of the cylinder, as calculated by the implementation in the Cylinder
class.
What’s next?
- If you found this story valuable, please consider clapping multiple times (this really helps a lot!)
- Hands-on Practice: Free Python Course
- Full series: 100 Days of Python
- Previous topic: Inheritance in Python
- Next topic: Multiple Inheritance in Python