Table of Contents
Introduction
In this tutorial, we will explore the concepts of inheritance and polymorphism in object-oriented programming using Python. We will learn how to create and use classes that inherit properties and methods from other classes, as well as how to leverage polymorphism to write flexible and reusable code.
By the end of this tutorial, you will have a solid understanding of inheritance and polymorphism, and you will be able to apply these concepts in your own Python projects.
Prerequisites
To follow along with this tutorial, you should have a basic understanding of object-oriented programming concepts in Python. Familiarity with classes, objects, and methods will be beneficial. Additionally, you should have Python installed on your machine. If you haven’t already installed Python, you can download it from the official Python website (https://www.python.org/downloads/).
Overview
What is Inheritance?
Inheritance is a fundamental concept in object-oriented programming that allows us to create new classes based on existing classes. The class that is being inherited from is called the parent class or superclass, and the class that inherits from it is called the child class or subclass. Inheritance allows the child class to inherit attributes and methods from the parent class, which helps in code reuse and promotes the idea of hierarchical classification of objects.
What is Polymorphism?
Polymorphism is another important concept in object-oriented programming that allows objects of different classes to be treated as objects of a common superclass. This means that a single function or method can be used to work with objects of different types. Polymorphism promotes code flexibility and enables the use of generic, reusable code.
In the sections below, we will dive deeper into inheritance and polymorphism and see how they can be implemented in Python.
Inheritance
In Python, inheritance is implemented using the syntax class ChildClass(ParentClass)
. This creates a new class (ChildClass
) that inherits from an existing class (ParentClass
).
Creating a Parent Class
Let’s start by creating a Person
class that represents a generic person with attributes like name
and age
.
```python
class Person:
def init(self, name, age):
self.name = name
self.age = age
def greet(self):
print(f"Hello, my name is {self.name} and I am {self.age} years old.")
# Create an instance of the Person class
person = Person("Alice", 25)
person.greet() # Output: Hello, my name is Alice and I am 25 years old.
``` Here, we have defined the `Person` class with an `__init__` method that initializes the `name` and `age` attributes. We have also defined a `greet` method that prints a greeting message using the `name` and `age` attributes.
Creating a Child Class
Now, let’s create a Student
class that inherits from the Person
class. In addition to the attributes and methods inherited from Person
, the Student
class will also have a school
attribute.
```python
class Student(Person):
def init(self, name, age, school):
super().init(name, age)
self.school = school
def study(self):
print(f"{self.name} is studying at {self.school}.")
# Create an instance of the Student class
student = Student("Bob", 20, "ABC High School")
student.greet() # Output: Hello, my name is Bob and I am 20 years old.
student.study() # Output: Bob is studying at ABC High School.
``` In this example, we define the `Student` class as a subclass of `Person`. The `__init__` method of the `Student` class calls the `__init__` method of the `Person` class using `super()`, but also initializes the `school` attribute.
Now, we can create instances of both the Person
class and the Student
class. The student
object can access the greet
method defined in the Person
class as well as the study
method defined in the Student
class.
Method Overriding
In addition to inheriting attributes and methods, child classes can also override methods defined in the parent class. ```python class Student(Person): def init(self, name, age, school): super().init(name, age) self.school = school
def greet(self):
print(f"Hello, my name is {self.name}, I am {self.age} years old, and I study at {self.school}.")
student = Student("Bob", 20, "ABC High School")
student.greet() # Output: Hello, my name is Bob, I am 20 years old, and I study at ABC High School.
``` In this example, we have overridden the `greet` method of the `Person` class in the `Student` class. When we call the `greet` method on a `Student` object, the overridden method in the `Student` class is executed instead of the method in the parent `Person` class.
This allows us to customize the behavior of methods in the child class while still inheriting common functionality from the parent class.
Polymorphism
Polymorphism allows us to treat objects of different classes as if they are of the same type. This enables us to write more generic and flexible code.
Polymorphic Functions
Let’s create a function called introduce
that can be used to introduce a Person
or a Student
object.
```python
def introduce(obj):
obj.greet()
person = Person("Alice", 25)
student = Student("Bob", 20, "ABC High School")
introduce(person) # Output: Hello, my name is Alice and I am 25 years old.
introduce(student) # Output: Hello, my name is Bob, I am 20 years old, and I study at ABC High School.
``` Here, we define the `introduce` function that takes an object as an argument and calls its `greet` method. Since both `Person` and `Student` classes have a `greet` method, we can pass objects of either class to the `introduce` function.
This demonstrates polymorphism in action. The introduce
function doesn’t need to know the specific class of the object it receives; it only relies on the fact that the object has a greet
method.
Polymorphic Methods
In addition to polymorphic functions, we can also have polymorphic methods within a class hierarchy. ```python class Animal: def sound(self): pass
class Cat(Animal):
def sound(self):
print("Meow")
class Dog(Animal):
def sound(self):
print("Woof")
animals = [Cat(), Dog()]
for animal in animals:
animal.sound()
``` In this example, we define an `Animal` class with a `sound` method that doesn't do anything. We then create two subclasses, `Cat` and `Dog`, which override the `sound` method with their own implementation.
We create a list called animals
that contains instances of Cat
and Dog
objects. By iterating over this list and calling the sound
method on each object, we can ensure that the appropriate implementation of sound
is called based on the actual class of the object.
Conclusion
In this tutorial, we have learned about inheritance and polymorphism in Python. Inheritance allows us to create new classes that inherit properties and methods from existing classes, promoting code reuse and hierarchical classification. Polymorphism enables us to treat objects of different classes as if they are of the same type, allowing for generic and flexible code.
By mastering these concepts, you can write more organized, reusable, and efficient code in your Python projects. Keep practicing and exploring different scenarios to deepen your understanding of object-oriented programming in Python.