One of the major benefits of object oriented programming is reuse of code and one of the ways this is achieved is through the inheritance mechanism. Inheritance can be best imagined as implementing a type and subtype relationship between classes.
Suppose you want to write a program which has to keep track of the teachers and students in a college. They have some common characteristics such as name, age and address. They also have specific characteristics such as salary, courses and leaves for teachers and, marks and fees for students.
You can create two independent classes for each type and process them but adding a new common characteristic would mean adding to both of these independent classes. This quickly becomes unwieldy.
A better way would be to create a common class called SchoolMember
and then have the teacher and student classes inherit from this
class i.e. they will become sub-types of this type (class) and then we can add specific
characteristics to these sub-types.
There are many advantages to this approach. If we add/change any functionality in
SchoolMember
, this is automatically reflected in the subtypes as
well. For example, you can add a new ID card field for both teachers and students by simply
adding it to the SchoolMember class. However, changes in the subtypes do not affect other
subtypes. Another advantage is that if you can refer to a teacher or student object as a
SchoolMember
object which could be useful in some situations such as
counting of the number of school members. This is called
polymorphism where a sub-type can be substituted in any
situation where a parent type is expected i.e. the object can be treated as an instance of
the parent class.
Also observe that we reuse the code of the parent class and we do not need to repeat it in the different classes as we would have had to in case we had used independent classes.
The SchoolMember
class in this situation is known as the
base class or the superclass. The
Teacher
and Student
classes are called the
derived classes or subclasses.
We will now see this example as a program.
Example 11.5. Using Inheritance
#!/usr/bin/python # Filename: inherit.py class SchoolMember: '''Represents any school member.''' def __init__(self, name, age): self.name = name self.age = age print '(Initialized SchoolMember: %s)' % self.name def tell(self): '''Tell my details.''' print 'Name:"%s" Age:"%s"' % (self.name, self.age), class Teacher(SchoolMember): '''Represents a teacher.''' def __init__(self, name, age, salary): SchoolMember.__init__(self, name, age) self.salary = salary print '(Initialized Teacher: %s)' % self.name def tell(self): SchoolMember.tell(self) print 'Salary: "%d"' % self.salary class Student(SchoolMember): '''Represents a student.''' def __init__(self, name, age, marks): SchoolMember.__init__(self, name, age) self.marks = marks print '(Initialized Student: %s)' % self.name def tell(self): SchoolMember.tell(self) print 'Marks: "%d"' % self.marks t = Teacher('Mrs. Shrividya', 40, 30000) s = Student('Swaroop', 22, 75) print # prints a blank line members = [t, s] for member in members: member.tell() # works for both Teachers and Students
$ python inherit.py (Initialized SchoolMember: Mrs. Shrividya) (Initialized Teacher: Mrs. Shrividya) (Initialized SchoolMember: Swaroop) (Initialized Student: Swaroop) Name:"Mrs. Shrividya" Age:"40" Salary: "30000" Name:"Swaroop" Age:"22" Marks: "75"
To use inheritance, we specify the base class names in a tuple following
the class name in the class definition. Next, we observe that the
__init__
method of the base class is explicitly
called using the self
variable so that we can initialize
the base class part of the object. This is very important to remember -
Python does not automatically call the constructor of the base class, you
have to explicitly call it yourself.
We also observe that we can call methods of the base class by prefixing
the class name to the method call and then pass in the
self
variable along with any arguments.
Notice that we can treat instances of Teacher
or
Student
as just instances of the
SchoolMember
when we use the
tell
method of the SchoolMember
class.
Also, observe that the tell
method of the
subtype is called and not the tell
method of the
SchoolMember
class. One way to understand this is that
Python always starts looking for methods in the type, which
in this case it does. If it could not find the method, it starts looking at the
methods belonging to its base classes one by one in the order they are specified
in the tuple in the class definition.
A note on terminology - if more than one class is listed in the inheritance tuple, then it is called multiple inheritance.