Inheritance and Polymorphism
Inheritance and polymorphism are core concepts of Object-Oriented Programming (OOP) that promote code reuse and flexibility.
Inheritance
Inheritance allows a class (child) to inherit attributes and methods from another class (parent). The child class can also have additional attributes and methods or override existing ones.
Syntax:
class Parent:
# Parent class
pass
class Child(Parent):
# Child class inherits Parent
pass
Example:
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
return "I make a sound."
class Dog(Animal):
def speak(self):
return "Woof!"
dog = Dog("Buddy")
print(dog.name) # Output: Buddy
print(dog.speak()) # Output: Woof!
The super()
Function
The super()
function allows the child class to call methods from the parent class.
Example:
class Animal:
def __init__(self, name):
self.name = name
class Dog(Animal):
def __init__(self, name, breed):
super().__init__(name) # Call the parent class's __init__
self.breed = breed
dog = Dog("Buddy", "Labrador")
print(dog.name) # Output: Buddy
print(dog.breed) # Output: Labrador
Method Overriding
A child class can override methods from the parent class to provide specialized behavior.
Example:
class Bird:
def fly(self):
return "I can fly!"
class Penguin(Bird):
def fly(self):
return "I cannot fly."
penguin = Penguin()
print(penguin.fly()) # Output: I cannot fly.
Polymorphism
Polymorphism allows objects of different classes to be treated as objects of a common parent class. This enables the same interface to handle different types of objects.
Example:
class Cat(Animal):
def speak(self):
return "Meow!"
animals = [Dog("Buddy"), Cat("Kitty")]
for animal in animals:
print(f"{animal.name}: {animal.speak()}")
# Output:
# Buddy: Woof!
# Kitty: Meow!
Abstract Classes and Methods
Abstract classes serve as blueprints for other classes. They can define methods that must be implemented by child classes.
- Use the
abc
module to create abstract classes.
Example:
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)
rect = Rectangle(4, 5)
print(rect.area()) # Output: 20
print(rect.perimeter()) # Output: 18
Multiple Inheritance
A class can inherit from more than one parent class.
Example:
class A:
def method_a(self):
return "Method from A"
class B:
def method_b(self):
return "Method from B"
class C(A, B):
pass
c = C()
print(c.method_a()) # Output: Method from A
print(c.method_b()) # Output: Method from B
Best Practices
- Use inheritance to model “is-a” relationships (e.g., a Dog is an Animal).
- Avoid deep inheritance hierarchies; they can make code harder to understand.
- Use
super()
to access parent class methods and ensure proper initialization. - Prefer composition over inheritance when a class “has-a” relationship (e.g., a Car has an Engine).
Practice Exercises
- Basic Inheritance:
- Create a parent class
Vehicle
with attributesbrand
andmodel
. - Create a child class
Car
with an additional attributeseats
.
- Create a parent class
- Method Overriding:
- Define a parent class
Shape
with a methodarea
. - Create child classes
Circle
andSquare
that overridearea
.
- Define a parent class
- Polymorphism:
- Create a parent class
Instrument
with a methodplay
. - Create child classes
Guitar
andPiano
that implementplay
.
- Create a parent class
- Abstract Classes:
- Define an abstract class
Animal
with an abstract methodsound
. - Implement
sound
in child classesDog
andCat
.
- Define an abstract class
Inheritance and polymorphism help create flexible, reusable, and organized code structures for complex applications.
Next Lesson: Encapsulation