Fundamentals 9 min read

Mastering Polymorphism: 10 Real-World Python Examples and When to Use Them

This article explains the core concept of polymorphism in object‑oriented programming, distinguishes compile‑time and runtime polymorphism, and provides ten practical Python examples—from animal sounds and shape drawing to payment processing, file handling, logging, and game characters—illustrating when and how to apply each technique.

Test Development Learning Exchange
Test Development Learning Exchange
Test Development Learning Exchange
Mastering Polymorphism: 10 Real-World Python Examples and When to Use Them

What Is Polymorphism?

Polymorphism is a fundamental concept in object‑oriented programming that allows objects to be treated as instances of their parent class while exhibiting different behaviors. It enables a single interface to work with multiple data types, making code more flexible and extensible.

Two Main Types

Compile‑time (static) polymorphism includes function overloading and operator overloading.

Runtime (dynamic) polymorphism is achieved through method overriding in subclasses.

Runtime Polymorphism – Method Overriding

When a subclass provides its own implementation of a method defined in the parent class, the subclass method is invoked at runtime.

class Animal:
    def speak(self):
        return "Animal makes a sound"

class Dog(Animal):
    def speak(self):
        return "Woof"

class Cat(Animal):
    def speak(self):
        return "Meow"

dog = Dog()
cat = Cat()
print(dog.speak())  # Output: Woof
print(cat.speak())  # Output: Meow

Typical use case: different subclasses need distinct behaviors while sharing a common interface.

Shape Drawing Example

class Shape:
    def draw(self):
        pass

class Circle(Shape):
    def draw(self):
        return "Draw circle"

class Rectangle(Shape):
    def draw(self):
        return "Draw rectangle"

shapes = [Circle(), Rectangle()]
for shape in shapes:
    print(shape.draw())  # Output: Draw circle, Draw rectangle

Use case: a graphics system can handle various shapes uniformly.

Payment Method Example

class Payment:
    def pay(self, amount):
        pass

class Alipay(Payment):
    def pay(self, amount):
        return f"Pay with Alipay {amount}元"

class WechatPay(Payment):
    def pay(self, amount):
        return f"Pay with WeChat {amount}元"

payment = Alipay()
print(payment.pay(100))  # Output: Pay with Alipay 100元

Use case: a payment system can switch between different providers without changing client code.

Compile‑Time Polymorphism – Method Overloading

Python does not support traditional method overloading, but similar effects can be achieved with default or variable arguments.

Calculator Overload Attempt

class Calculator:
    def add(self, a, b):
        return a + b
    def add(self, a, b, c):
        return a + b + c

calc = Calculator()
print(calc.add(1, 2))  # Error in Python

Note: Python will keep the last definition, so the two‑parameter version is overwritten.

Variable‑Argument Solution

class Calculator:
    def add(self, *args):
        return sum(args)

calc = Calculator()
print(calc.add(1, 2))        # Output: 3
print(calc.add(1, 2, 3))     # Output: 6

Variable arguments provide a flexible way to mimic overload behavior.

Additional Application Scenarios

Database Access Layer

class DatabaseAccessor:
    def query(self, sql):
        pass

class MySQLAccessor(DatabaseAccessor):
    def query(self, sql):
        return f"Execute in MySQL: {sql}"

class OracleAccessor(DatabaseAccessor):
    def query(self, sql):
        return f"Execute in Oracle: {sql}"

accessor = MySQLAccessor()
print(accessor.query("SELECT * FROM users"))
# Output: Execute in MySQL: SELECT * FROM users

Polymorphism lets the same client code work with different database implementations.

File Operations

class FileHandler:
    def read(self, file):
        pass

class TextFileHandler(FileHandler):
    def read(self, file):
        return f"Read text file: {file}"

class ImageFileHandler(FileHandler):
    def read(self, file):
        return f"Read image file: {file}"

handler = TextFileHandler()
print(handler.read("example.txt"))
# Output: Read text file: example.txt

Different file types can be processed through a common interface.

Logging System

class Logger:
    def log(self, message):
        pass

class FileLogger(Logger):
    def log(self, message):
        return f"Write log to file: {message}"

class ConsoleLogger(Logger):
    def log(self, message):
        return f"Print log to console: {message}"

logger = ConsoleLogger()
print(logger.log("This is a log message"))
# Output: Print log to console: This is a log message

Polymorphism enables easy swapping of logging destinations.

Game Characters

class Character:
    def attack(self):
        pass

class Warrior(Character):
    def attack(self):
        return "Warrior attacks with sword"

class Mage(Character):
    def attack(self):
        return "Mage casts a spell"

character = Warrior()
print(character.attack())  # Output: Warrior attacks with sword

Each character class defines its own attack behavior while sharing the same interface.

Notification System

class Notification:
    def send(self, message):
        pass

class EmailNotification(Notification):
    def send(self, message):
        return f"Send email: {message}"

class SMSNotification(Notification):
    def send(self, message):
        return f"Send SMS: {message}"

notification = EmailNotification()
print(notification.send("Welcome!"))
# Output: Send email: Welcome!

Polymorphism allows the notification service to switch between email, SMS, or other channels without altering the caller.

Summary and Recommendations

Through the ten code examples we explored both runtime and compile‑time polymorphism. Runtime polymorphism (method overriding) lets subclasses provide specialized behavior, while compile‑time polymorphism (method overloading) can be simulated in Python with default or variable arguments. The key benefits of polymorphism are increased flexibility, extensibility, and maintainability. It is widely applicable in graphics rendering, database access, file handling, logging, game development, payment processing, and notification services. Mastering polymorphism will help you write more modular code and tackle complex design problems more effectively.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Design PatternsPythonobject‑oriented programmingPolymorphismMethod OverloadingMethod Overriding
Test Development Learning Exchange
Written by

Test Development Learning Exchange

Test Development Learning Exchange

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.