What is the difference between polymorphism and inheritance in Python?

Bryan 178 Published: 11/07/2024

What is the difference between polymorphism and inheritance in Python?

I'd be happy to explain the differences between polymorphism and inheritance in Python!

Inheritance

Inheritance is a fundamental concept in object-oriented programming (OOP). In Python, it allows one class to inherit the attributes and methods of another class. The child class inherits all the properties and behavior of the parent class, which can then be overridden or extended by the child class.

To illustrate this, let's consider an example:

class Animal:

def sound(self):

print("The animal makes a sound.")

class Dog(Animal):

def sound(self):

print("The dog barks.")

In this example, Dog is a subclass of Animal. When we create an instance of the Dog class and call its sound() method, it overrides the parent class's implementation:

my_dog = Dog()

my_dog.sound() # Output: "The dog barks."

Polymorphism

Polymorphism is a broader concept that goes beyond inheritance. It refers to the ability of an object to take on multiple forms. In Python, this can be achieved through method overriding or method overloading.

Method Overriding: This is when a child class provides a different implementation for a method that is already defined in its parent class.

For example:

class Shape:

def area(self):

pass

class Circle(Shape):

def area(self):

return 3.14 * 2 ** 2

Here, the Circle class overrides the area() method of its parent class Shape, providing a specific implementation for calculating the area of a circle.

Method Overloading: This is when multiple methods with the same name can be defined in a class, but they take different numbers or types of arguments. Python does not support method overloading natively, but you can achieve similar behavior using duck typing (more on this below).

Duck Typing

In Python, duck typing allows for polymorphism without explicit inheritance. It's called "duck typing" because if it walks like a duck and quacks like a duck, then it's probably a duck.

Let's consider an example:

def make_sound(obj):

obj.sound()

class Animal:

def sound(self):

print("The animal makes a sound.")

class Dog(Animal):

def sound(self):

print("The dog barks.")

make_sound(Animal()) # Output: "The animal makes a sound."

make_sound(Dog()) # Output: "The dog barks."

In this example, the make_sound() function can work with instances of both Animal and Dog classes without any explicit inheritance or polymorphism. This is because the sound() method is defined in the Animal class, which is inherited by the Dog class.

Conclusion

To summarize:

Inheritance allows a child class to inherit attributes and methods from its parent class. Polymorphism enables an object to take on multiple forms through method overriding or method overloading (in languages that support it). Duck typing in Python provides a way for polymorphism without explicit inheritance, allowing objects of different classes to behave similarly.

I hope this explanation has helped you understand the differences between these two important concepts!

Python polymorphism examples

Here are some Python polymorphism examples:

Example 1: Method Overriding

class Animal:

def sound(self):

print("The animal makes a sound.")

class Dog(Animal):

def sound(self):

print("The dog barks.")

class Cat(Animal):

def sound(self):

print("The cat meows.")

dog = Dog()

cat = Cat()

dog.sound() # Output: The dog barks.

cat.sound() # Output: The cat meows.

Here, the sound method is overridden in both the Dog and Cat classes, but they still inherit from the Animal class. This demonstrates polymorphism.

Example 2: Method Overloading

class Calculator:

def calculate(self, x):

print(f"The result of {x} is {x}.")

def calculate(self, x, y):

print(f"The result of {x} and {y} is {x + y}.")

calculator = Calculator()

calculator.calculate(5) # Output: The result of 5 is 5.

calculator.calculate(5, 3) # Output: The result of 5 and 3 is 8.

Here, the calculate method can take either one or two arguments, depending on which method is called. This demonstrates method overloading.

Example 3: Polymorphic Functions

def greet(animal):

if isinstance(animal, Dog):

print("Woof!")

elif isinstance(animal, Cat):

print("Meow!")

dog = Dog()

cat = Cat()

greet(dog) # Output: Woof!

greet(cat) # Output: Meow!

Here, the greet function can take an instance of either the Dog or Cat class, and respond accordingly. This demonstrates polymorphism.

Example 4: Abstract Classes with Polymorphic Methods

from abc import ABC, abstractmethod

class Shape(ABC):

@abstractmethod

def area(self):

pass

class Circle(Shape):

def init(self, radius):

self.radius = radius

def area(self):

return 3.14 * (self.radius ** 2)

class Rectangle(Shape):

def init(self, width, height):

self.width = width

self.height = height

def area(self):

return self.width * self.height

shapes = [Circle(5), Rectangle(4, 6)]

for shape in shapes:

print(f"Area of {shape.class.name}: {shape.area()}")

Here, the Shape class is abstract and defines an interface, while the Circle and Rectangle classes implement that interface. The polymorphic method area can be called on instances of either class.

These are just a few examples of Python polymorphism. Polymorphism allows for more flexibility and reusability in your code, which is especially important when working with complex systems or large datasets.