Java JavaScript Python C# C C++ Go Kotlin PHP Swift R Ruby TypeScript Scala SQL Perl rust VisualBasic Matlab Julia

Polymorphism → Overriding

Polymorphism

Overriding

Method Overriding in Python

Method overriding is a powerful feature in object-oriented programming (OOP) that allows a subclass to provide a specific implementation for a method that is already defined in its superclass (parent class). This provides a way to customize the behavior of inherited methods without altering the superclass's code. Python, being a dynamically typed language, handles method overriding in a slightly different way than statically typed languages like Java or C++. Let's explore it with multiple examples.

Key Characteristics

Inheritance: Method overriding is intrinsically linked to inheritance. A subclass must inherit from a superclass to override its methods. Method Signature: The overriding method in the subclass must have the *exact same* name and parameters (signature) as the method in the superclass. Any difference in the signature creates a new method, not an override. Dynamic Dispatch: Python uses dynamic dispatch (also called runtime polymorphism) to determine which method to execute. The actual method called is decided at runtime based on the object's type, not its declared type. Example 1: Basic Overriding
Simple Overriding example class Animal: def speak(self): print("Generic animal sound") class Dog(Animal): def speak(self): print("Woof!") class Cat(Animal): def speak(self): print("Meow!") animal = Animal() dog = Dog() cat = Cat() animal.speak() dog.speak() cat.speak()

Output

Generic animal sound Woof! Meow!
Here, `Dog` and `Cat` override the `speak()` method from the `Animal` class. Each subclass provides its own specific sound.
Example 2: Overriding with Parameters
Python method Overriding with Parameters class Shape: def area(self, length, width): print("Calculating area for a generic shape...") return length * width class Rectangle(Shape): def area(self, length, width): print("Calculating area for a rectangle...") return length * width class Square(Shape): def area(self, side): #Note: Different signature. This doesn't override. print("Calculating area for a square...") return side * side shape = Shape() rectangle = Rectangle() square = Square() print(shape.area(5, 10)) print(rectangle.area(5, 10)) print(square.area(5))

Output

Calculating area for a generic shape... 50 Calculating area for a rectangle... 50 Calculating area for a square... 25
In this example, `Rectangle` correctly overrides `area()`, maintaining the same signature. `Square` however, defines a different `area()` method with a single parameter (`side`), thus it doesn't override the superclass method, it simply defines its own.
Example 3: Calling Superclass Method Sometimes, you might want to extend the functionality of the superclass method instead of completely replacing it. Python's `super()` function allows you to achieve this:
Calling Superclass Method in python class Animal: def __init__(self, name): self.name = name def speak(self): print(f"{self.name} makes a generic sound") class Dog(Animal): def speak(self): super().speak() # Call the superclass speak method print(f"{self.name} barks!") dog = Dog("Buddy") dog.speak()

Output

Buddy makes a generic sound Buddy barks!
Here, `Dog`'s `speak()` method first calls the `Animal` class's `speak()` using `super().speak()` and then adds its own specific bark.
Example 4: Handling Exceptions in Overriding Overriding can also be used to handle exceptions differently in subclasses.
Handling Exceptions in Overriding class DatabaseOperation: def execute(self, query): try: # Simulate database interaction result = f"Query '{query}' executed successfully" return result except Exception as e: print(f"Error executing query: {e}") return None class SecureDatabaseOperation(DatabaseOperation): def execute(self, query): try: # Add security checks before execution. if query.lower().startswith("drop"): raise Exception("DROP queries are forbidden!") result = super().execute(query) # Execute the base operation return result except Exception as e: print(f"SecureDatabaseOperation caught an error: {e}") return None db_op = DatabaseOperation() secure_db_op = SecureDatabaseOperation() print(db_op.execute("SELECT * FROM users")) print(secure_db_op.execute("SELECT * FROM users")) print(secure_db_op.execute("DROP TABLE users"))

Output

Query 'SELECT * FROM users' executed successfully Query 'SELECT * FROM users' executed successfully SecureDatabaseOperation caught an error: DROP queries are forbidden! None
In this, the subclass adds additional security checks and handles exceptions differently. These examples demonstrate the versatility and power of method overriding in Python. By carefully choosing when and how to override methods, you can create flexible and robust object-oriented designs. Remember the crucial role of the method signature in achieving true overriding and the power of `super()` to combine superclass and subclass behavior.

Tutorials