Inheritance and Polymorphism
Lesson 18: Inheritance and Polymorphism
Learning Objectives
By the end of this lesson, you will be able to: 1. Understand the concepts of inheritance and polymorphism in Python. 2. Create a base class and derived classes to demonstrate inheritance. 3. Implement method overriding to achieve polymorphism. 4. Recognize real-world analogies and applications of these concepts.
Introduction to Inheritance
Inheritance is a fundamental concept in object-oriented programming (OOP) that allows a class (called a derived class or child class) to inherit attributes and methods from another class (called a base class or parent class). This promotes code reusability and establishes a hierarchical relationship between classes.
Key Terms
- Base Class (Parent Class): The class whose properties and methods are inherited.
- Derived Class (Child Class): The class that inherits from the base class.
- Method Overriding: A feature that allows a derived class to provide a specific implementation of a method that is already defined in its base class.
Why Use Inheritance?
Inheritance is useful for several reasons: - Code Reusability: You can reuse existing code, which reduces redundancy. - Logical Structure: Helps in organizing code logically by grouping related classes. - Ease of Maintenance: Changes made to the base class automatically reflect in derived classes.
Basic Syntax of Inheritance
In Python, you can create a derived class by specifying the base class in parentheses after the class name. Here is the basic syntax:
class BaseClass:
# Base class code
class DerivedClass(BaseClass):
# Derived class code
Example of Inheritance
Let’s create a simple example to illustrate inheritance. We will define a base class Animal and a derived class Dog.
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
return "Some sound"
class Dog(Animal):
def speak(self):
return "Woof!"
# Creating an instance of Dog
my_dog = Dog("Buddy")
print(my_dog.name) # Output: Buddy
print(my_dog.speak()) # Output: Woof!
Explanation
- Animal Class: This is the base class with an initializer (
__init__) that sets the name of the animal and a methodspeak()that returns a generic sound. - Dog Class: This is the derived class that inherits from
Animal. It overrides thespeak()method to provide a specific sound for dogs. - Creating an Instance: We create an instance of
Dogcalledmy_dog, set its name to "Buddy", and call thespeak()method, which returns "Woof!".
Understanding Polymorphism
Polymorphism is another key concept in OOP that allows objects of different classes to be treated as objects of a common base class. It enables a single interface to represent different underlying forms (data types).
Key Terms
- Polymorphism: The ability to present the same interface for different underlying data types.
Method Overriding and Polymorphism
Method overriding is a way to achieve polymorphism. In our previous example, both the Animal and Dog classes have a method called speak(), but they behave differently based on the object type. This is polymorphism in action.
Example of Polymorphism
Let’s extend our previous example to include another derived class, Cat.
class Cat(Animal):
def speak(self):
return "Meow!"
# Function that demonstrates polymorphism
def animal_sound(animal):
print(animal.speak())
# Creating instances of Dog and Cat
my_dog = Dog("Buddy")
my_cat = Cat("Whiskers")
# Calling the function with different animal types
animal_sound(my_dog) # Output: Woof!
animal_sound(my_cat) # Output: Meow!
Explanation
- Cat Class: This is another derived class that overrides the
speak()method to return "Meow!". - animal_sound Function: This function takes an
animalobject and calls itsspeak()method. It works with any object that is an instance ofAnimalor its derived classes. - Demonstration of Polymorphism: We create instances of
DogandCat, and pass them to theanimal_sound()function. The correctspeak()method is called based on the actual object type, demonstrating polymorphism.
Real-World Analogy
Think of inheritance as a family tree:
- The Animal class is like a grandparent, providing common traits (like speak()) to all animals.
- The Dog and Cat classes are like grandchildren, inheriting traits from the grandparent but also defining their unique traits (specific sounds).
Common Mistakes and How to Avoid Them
- Forgetting to Call the Base Class Constructor: If your derived class has its own
__init__method, remember to call the base class constructor usingsuper(). For example:
class Dog(Animal):
def __init__(self, name, breed):
super().__init__(name) # Call to the base class constructor
self.breed = breed
- Not Overriding Methods Correctly: Ensure that the method name in the derived class matches exactly with the base class method name, including case sensitivity.
Best Practices
- Use inheritance when there is a clear hierarchical relationship between classes.
- Prefer composition over inheritance when possible. Sometimes, it’s better to have classes that contain instances of other classes rather than inherit from them.
- Keep your class hierarchies shallow. Deep hierarchies can make your code complex and hard to maintain.
Key Takeaways
- Inheritance allows a class to inherit attributes and methods from another class, promoting code reusability.
- Polymorphism enables different classes to be treated as instances of the same class through method overriding.
- Proper usage of inheritance and polymorphism can lead to cleaner, more maintainable code.
Transition to the Next Lesson
In this lesson, we explored the concepts of inheritance and polymorphism in Python, which are essential for creating flexible and reusable code. In the next lesson, we will dive into Working with JSON Data, where you will learn how to handle JSON in Python, a widely-used format for data interchange. Stay tuned!
Exercises
Practice Exercises
-
Basic Inheritance: Create a base class called
Vehiclewith attributesmakeandmodel. Create derived classesCarandMotorcyclethat inherit fromVehicleand add an additional attributenum_wheels. Implement a methoddescribe()in each derived class that prints a description of the vehicle. -
Polymorphism with Shapes: Create a base class
Shapewith a methodarea(). Create derived classesCircleandRectanglethat implement thearea()method. Create a functionprint_area()that takes aShapeobject and prints its area. -
Animal Sounds: Extend the previous animal example by adding another derived class called
Birdthat overrides thespeak()method to return "Tweet!". Create a list of different animal objects and iterate through the list, calling thespeak()method for each.
Practical Assignment
Create a mini-project that simulates a library system. Define a base class Book with attributes like title, author, and year. Create derived classes Ebook and PrintedBook that add specific attributes (like file_size for Ebook and page_count for PrintedBook). Implement methods to display book information and a method to check out a book, indicating whether it is available or checked out. Use polymorphism to handle the display method for both types of books.
Summary
- Inheritance allows classes to inherit properties and methods from other classes, promoting code reuse.
- A base class is the parent class, while derived classes are the child classes that inherit from it.
- Polymorphism allows different classes to be treated as instances of the same class through method overriding.
- Method overriding enables derived classes to provide specific implementations of methods defined in the base class.
- Properly using inheritance and polymorphism can lead to cleaner and more maintainable code.