Hello, future Python expert! Today, we'll dig into a significant feature of Object-Oriented Programming (OOP) — inheritance. Much like children inheriting characteristics from their parents, child classes in OOP can adopt properties and behaviors from parent classes in the same vein.
Our goal here is to comprehend the purpose, different types, and the implementation of inheritance, with speculative attention on simple inheritance. With inheritance, we can reuse code, minimizing repetition and maximizing efficiency.
Inheritance in OOP mirrors inherited characteristics in life. We create child
classes that receive properties and behaviors from a parent
class. Consider a school environment: all kinds of teachers share common actions (such as teaching), regardless of the subjects they teach. We could create a base Teacher
class with these shared behaviors and then generate MathTeacher,
ScienceTeacher,
etc., which inherit these common behaviors and add others unique to their respective subjects.
Python supports multiple types of inheritance — including single, multiple, multilevel, and more. In this lesson, we'll turn our attention to single inheritance, where a child class inherits from a solitary parent class. This type of inheritance is the most common and basic among all existing.
Diagram:
Markdown1 BaseClass
2 |
3 DerivedClass
Let's examine how to implement inheritance in Python. We begin by creating a Teacher
base class:
Python1class Teacher: 2 def __init__(self, name): 3 self.name = name 4 5 def teach(self): 6 print(self.name + " is teaching.")
Next, a MathTeacher
child class inherits from Teacher
:
Python1class MathTeacher(Teacher): 2 def teach_math(self): 3 print(self.name + " is teaching math.")
The MathTeacher
class inherits the Teacher
class because in the class constructor, we have class MathTeacher(Teacher).
The MathTeacher
inherits the teach
method from Teacher
and incorporates a teach_math
method:
Python1math_teacher = MathTeacher("Mr. Johnson") 2math_teacher.teach() # Prints: "Mr. Johnson is teaching." 3math_teacher.teach_math() # Prints: "Mr. Johnson is teaching math."
In the above code, math_teacher
can invoke both teach
and teach_math
methods because teach
was inherited from the Teacher
class.
Inheritance enables code reuse; this is evident when the MathTeacher
class utilizes the teach
method from the Teacher
class without the necessity to re-implement it. Moreover, Python allows method overriding. If a base-class method does not suit the child's class, it can be overridden — for example, a math teacher doesn't just 'teach'; they 'explain':
Python1class MathTeacher(Teacher): 2 def teach(self): 3 print(self.name + " is explaining math.") 4 5math_teacher = MathTeacher("Mr. Johnson") 6math_teacher.teach() # Prints: "Mr. Johnson is explaining math."
The method in the MathTeacher
class will supersede the one in the Teacher
class. Note how we called the same teach()
method on the MathTeacher
instance but observed a different behavior - that's because the parent method from the Teacher
class has been overridden.
So far, we've seen how a child class inherits properties and behaviors from a parent class. But what if we want to initialize some attributes in the parent and others in the child class? That's where super()
comes in.
The super()
function is a built-in function in Python that allows us to refer to the parent class, typically used in the constructor of the child class. It lets us call methods from the parent class without naming the parent class explicitly, making our code more maintainable.
Let's look at an example. Suppose we have a Person
class with attributes name
and age
, and a Student
class that extends Person
and has an additional attribute student_id
:
Python1class Person: 2 def __init__(self, name, age): 3 self.name = name 4 self.age = age 5 6class Student(Person): 7 def __init__(self, name, age, student_id): 8 super().__init__(name, age) # call the constructor of Person 9 self.student_id = student_id 10 11student = Student('Alex', 20, 'S1023') 12print(student.name) # Outputs: Alex 13print(student.age) # Outputs: 20 14print(student.student_id) # Outputs: S1023
In this code, Student
's constructor calls super().__init__(name, age)
to use Person
's constructor to set the name
and age
attributes. Then it adds a student_id
attribute.
In summary, the super()
function provides a way to call parent class methods, helping to avoid code duplication and enhancing code maintainability.
Well done! You're now familiar with Python inheritance. We've learned its definition, why it's imperative, and implemented simple inheritance. To solidify your new skills, try applying these concepts with upcoming exercises.
In the forthcoming lessons, we'll be delving into the other potent components of OOP in Python — encapsulation and polymorphism. So, stay tuned for an exciting journey into the cosmos of object-oriented programming!