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 your college. They have some common characteristics such as name, age and address. They also have some specific characteristics. For example, teachers have salary, courses and leaves and students have marks and fees.
Although you could have created two independent classes for each type, 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. be sub-types of this type (class) and adding the specific characteristics or functionality to the sub-type.
There are many advantages to this approach. One is that you can refer to a teacher or student object as a SchoolMember object, which could be helpful in some situations such as counting 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 a parent class.
Another advantage is that changes to the SchoolMember class are reflected in the teacher and student classes as well. For example, you can add a new identification number for each school member i.e. both teachers and students using this mechanism.
More importantly, we reuse the code of the parent class and we do not need to repeat it elsewhere such as in the sub-types.
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.
Example 11.4. Inheritance
#!/usr/bin/python # Filename: inheritance.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): 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. Abraham', 40, 30000) s = Student('Swaroop', 21, 75) print # prints a blank line members = [t, s] for member in members: member.tell() # Works for instances of Student as well as Teacher
$ python inheritance.py (Initialized SchoolMember: Mrs. Abraham) (Initialized Teacher: Mrs. Abraham) (Initialized SchoolMember: Swaroop) (Initialized Student: Swaroop) Name:"Mrs. Abraham" Age:"40" Salary:"30000" Name:"Swaroop" Age:"21" Marks:"75"
To use inheritance, we specify the base class names in a parenthesized list following the class name in the class definition. Next, we can observe that the __init__ method of the base class is explicitly called using the self variable so as to initialize the base class part of the object. We can also observe that we can treat instances of Teacher or Student as just instances of SchoolMember when we use the tell method of the SchoolMember class.
A note on terminology - if more than one class is listed in the inheritance list, then it is called multiple inheritance.