Method Overriding and Polymorphism
Lesson Overview
Method Overriding happens when a child class provides its own version of a method that is already defined in its parent class. This is a key part of Polymorphism (meaning "many forms"), which allows different objects to respond to the same method call in their own unique way. It lets you write flexible code where a single function can handle different types of objects (like a "Car" and a "Boat") without needing to know exactly which one it is
Lesson Content
The Payment Problem: Why We Need Inheritance and Polymorphism
Let's say you're building a billing system for an e-commerce platform. Customers can pay using:
- UPI (instant bank transfer)
- Bank Transfer (manual NEFT/RTGS)
- Credit Card (swipe/tap with OTP)
- Debit Card (PIN-based authorization)
All of them need to accomplish the same goal: deduct money from the customer and update the balance. But the way each payment happens is completely different.Let's explore different ways to implement this in code, from the simplest (but problematic) to the most elegant (using OOP principles).
Approach 1: Writing Separate Functions (The Messy Way)
You might think: "Let me just write four separate functions."
def pay_with_upi(amount):
print("Opening UPI app...")
print("Scanning QR code...")
print(f"₹{amount} deducted from bank account.")
print("Balance updated.")
def pay_with_bank_transfer(amount):
print("Entering bank details...")
print("Verifying IFSC code...")
print(f"₹{amount} transferred via NEFT.")
print("Balance updated.")
def pay_with_credit_card(amount):
print("Swiping card...")
print("Sending OTP...")
print(f"₹{amount} charged to credit account.")
print("Balance updated.")
def pay_with_debit_card(amount):
print("Inserting card...")
print("Enter PIN...")
print(f"₹{amount} deducted from savings account.")
print("Balance updated.") Problems with This Approach:
- Code Duplication: Notice "Balance updated" appears in all four functions. If you need to change how balance updates work (e.g., send an SMS), you have to edit four places. High chance of bugs.
- No Common Interface: Your checkout system has to check: "Is this UPI? Call
pay_with_upi(). Is this a card? Callpay_with_credit_card()..." This becomes a nightmare with 20 payment methods. - Not Scalable: Adding a new payment method (like International Transfer) means writing a brand new function and updating every part of the code that handles payments.
Approach 2: Using Inheritance (The Smart Way)
Instead, let's think like this:
"All payment methods do the same thing at a high level—they PAY and update the balance. But the internal steps are different."
This is where inheritance shines. We create a Parent Class called PaymentMethod that defines the common structure, and then create Child Classes for each specific payment type.
Step 1: The Parent Class (The Blueprint)
class PaymentMethod:
def pay(self, amount):
# This is the "generic" version
print("Processing payment...")
print(f"₹{amount} deducted.")
print("Balance updated.") This parent says: "Every payment method must have a pay() function." But right now, it's just a generic class that can be used by its child classes
Step 2: The Problem—One Size Doesn't Fit All
If we create child classes and don't override the pay() method, they'll all behave exactly the same:
class UPI(PaymentMethod):
pass # No override
class CreditCard(PaymentMethod):
pass # No override
# Both will print "Processing payment..." (generic message)
But we know UPI and Credit Cards work differently. UPI scans a QR code. Credit cards need OTP verification. The parent's generic logic doesn't capture these differences
💬 Comments (0)
Login to join the discussion
No comments yet. Be the first to share your thoughts!