What is Polymorphism?
Polymorphism is a core concept in object-oriented programming (OOP) that allows objects of different classes to be treated as objects of a common superclass. It comes from Greek words meaning "many forms".
# Polymorphism allows the same interface for different data types
class Dog:
def speak(self):
return "Woof!"
class Cat:
def speak(self):
return "Meow!"
# Polymorphic function
def animal_sound(animal):
print(animal.speak())
# Using polymorphism
dog = Dog()
cat = Cat()
animal_sound(dog) # Output: Woof!
animal_sound(cat) # Output: Meow!
Polymorphism enables writing more flexible and maintainable code by allowing different objects to respond to the same method call in different ways.
Types of Polymorphism
Python supports several types of polymorphism:
# 1. Duck Typing (Dynamic Polymorphism)
class Duck:
def sound(self):
return "Quack!"
class Car:
def sound(self):
return "Vroom!"
# The function doesn't care about the class, only the method
def make_sound(obj):
print(obj.sound())
# Both work despite being different classes
make_sound(Duck()) # Quack!
make_sound(Car()) # Vroom!
# 2. Operator Overloading
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def __add__(self, other):
return Vector(self.x + other.x, self.y + other.y)
v1 = Vector(2, 3)
v2 = Vector(1, 4)
v3 = v1 + v2 # Uses __add__ method
print(f"Vector: ({v3.x}, {v3.y})") # Vector: (3, 7)
Method Overriding
Method overriding occurs when a child class provides a specific implementation of a method that is already defined in its parent class.
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
return f"{self.name} makes a sound"
class Dog(Animal):
def speak(self):
return f"{self.name} says Woof!"
class Cat(Animal):
def speak(self):
return f"{self.name} says Meow!"
# Creating objects
animal = Animal("Generic Animal")
dog = Dog("Rex")
cat = Cat("Whiskers")
# Polymorphic behavior
print(animal.speak()) # Generic Animal makes a sound
print(dog.speak()) # Rex says Woof!
print(cat.speak()) # Whiskers says Meow!
Abstract Base Classes (ABCs)
ABCs define a blueprint for other classes. They can't be instantiated themselves but ensure derived classes implement specific methods.
from abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
def area(self):
pass
@abstractmethod
def perimeter(self):
pass
class Rectangle(Shape):
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
def perimeter(self):
return 2 * (self.width + self.height)
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14 * self.radius ** 2
def perimeter(self):
return 2 * 3.14 * self.radius
# Polymorphic function
def print_shape_info(shape):
print(f"Area: {shape.area()}, Perimeter: {shape.perimeter()}")
# Using polymorphism with ABC
rect = Rectangle(4, 5)
circle = Circle(7)
print_shape_info(rect) # Area: 20, Perimeter: 18
print_shape_info(circle) # Area: 153.86, Perimeter: 43.96
Duck Typing
Python uses duck typing ("If it walks like a duck and quacks like a duck, it must be a duck") where the type or class of an object is less important than the methods it defines.
class Book:
def __init__(self, title, author):
self.title = title
self.author = author
def __str__(self):
return f"{self.title} by {self.author}"
class Movie:
def __init__(self, title, director):
self.title = title
self.director = director
def __str__(self):
return f"{self.title} directed by {self.director}"
# Function that works with any object that has __str__
def display_info(item):
print(item)
# Both work despite being different classes
book = Book("Python Crash Course", "Eric Matthes")
movie = Movie("Inception", "Christopher Nolan")
display_info(book) # Python Crash Course by Eric Matthes
display_info(movie) # Inception directed by Christopher Nolan
Python Polymorphism Videos
Master Python polymorphism with these handpicked YouTube tutorials:
Understand polymorphism in OOP context:
Python's dynamic typing approach:
Customizing inherited methods:
Creating interfaces in Python: