Skip to main content

3.4 - Inheritance and Polymorphism

3.4.1 - Introduction to Inheritance

Inheritance allows a new class to extend an existing class. The new class, known as a subclass, inherits attributes and methods from the existing class, known as a superclass.

Example 1: Basic Inheritance

class Animal:
def __init__(self, name):
self.name = name

def speak(self):
raise NotImplementedError("Subclass must implement abstract method")

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

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

dog = Dog("Buddy")
cat = Cat("Whiskers")
print(dog.speak()) # Output: Woof!
print(cat.speak()) # Output: Meow!

Example 2: Inheritance with Constructor Overriding

class Bird(Animal):
def __init__(self, name, can_fly):
super().__init__(name)
self.can_fly = can_fly

def speak(self):
return "Chirp!" if self.can_fly else "Squawk!"

parrot = Bird("Polly", True)
penguin = Bird("Pingu", False)
print(parrot.speak(), parrot.can_fly) # Output: Chirp! True
print(penguin.speak(), penguin.can_fly) # Output: Squawk! False

3.4.2 - Types of Inheritance

Python supports different types of inheritance, including single, multi-level, hierarchical, and multiple inheritances.

Example 1: Single Inheritance

class Reptile(Animal):
def speak(self):
return "Hiss!"

snake = Reptile("Sly")
print(snake.speak()) # Output: Hiss!

Example 2: Multiple Inheritance

class Amphibian(Animal):
def live_in_water(self):
return True

class Frog(Amphibian, Reptile):
pass

frog = Frog("Kermit")
print(frog.speak()) # Output: Hiss!
print(frog.live_in_water()) # Output: True

3.4.3 - Introduction to Polymorphism

Polymorphism in Python allows methods to have the same name but behave differently in different contexts, particularly in different subclasses.

Example 1: Method Overriding

class Fish(Animal):
def speak(self):
return "Blub!"

nemo = Fish("Nemo")
print(nemo.speak()) # Output: Blub!

Example 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, 4)
v2 = Vector(1, 3)
result = v1 + v2
print(result.x, result.y) # Output: 3 7

3.4.4 Abstract Classes and Interfaces

In Python, abstract classes and interfaces enforce a structure for subclasses, dictating methods that must be implemented.

Example 1: Abstract Base Class

from abc import ABC, abstractmethod

class Shape(ABC):
@abstractmethod
def area(self):
pass

class Rectangle(Shape):
def __init__(self, width, height):
self.width = width
self.height = height

def area(self):
return self.width * self.height

rect = Rectangle(3, 4)
print(rect.area()) # Output: 12

Example 2: Interface Using Abstract Methods

class Polygon(Shape):
@abstractmethod
def sides(self):
pass

class Triangle(Polygon):
def area(self):
# Implementation for area
pass

def sides(self):
return 3

tri = Triangle()
print(tri.sides()) # Output: 3