Friday, October 16, 2009

Python Super Classes

The Python programming language is considered to be an object-oriented language. This means that not only must it support classes, but it must also support inheritance in one form or another. Inheritance is the principle of object-oriented software development that allows developers to say class A "is a kind of" class B.

Not all object-oriented languages support it, but multiple inheritance is another form of inheritance what allows developers to say class A "is a kind of" class B "and is also a kind of" class C. The Python programming language does support multiple inheritance and can support designs that employ the principle when needed.

Opponents of multiple inheritance say that it is an unnecessary feature of object oriented languages and in most cases, they are correct. Not necessarily correct about the fact that multiple inheritance shouldn't be a language feature, but about the design itself. Like anything else, multiple inheritance can be abused and actually hurt the software. Most of the time, it isn't needed and something more simplistic in design terms is ideal.

Consider the following class hierarchy. Here we have a Person class that acts as the root of the hierarchy. Next, we have an Adult and a Remote class, both of which inherit directly from Person. Finally, the Student class inherits from both Adult and Remote. The Student class uses multiple inheritance.

This is an example of where multiple inheritance may come in handy. The Remote class represents something that isn't local. This could be a Student or something else in the system. Since it is required that Student inherit from Adult, it makes sense that it also be able to inherit from Remote. A student can be both things.

Below is an example of this class hierarchy defined in Python. The super() function really helps us here because the Student class would otherwise need to invoke the individual constructors of each of its' super classes. Not only is this less code, it is also more generic of a design. All Student instances base class constructors will continue to be invoked correctly, even as these base classes change.
#Example; Using the super() function.

#Root class.
class Person(object):
def __init__(self):
super(Person, self).__init__()
print "Person"

#Adult class. Inherits from Person.
class Adult(Person):
def __init__(self):
super(Adult, self).__init__()
print "Adult"

#Remote class. Inherits from Person.
class Remote(Person):
def __init__(self):
super(Remote, self).__init__()
print "Remote"

#Student class. Inherits from both Adult and Remote.
class Student(Adult, Remote):
def __init__(self):
super(Student, self).__init__()
print "Student"

if __name__=="__main__":
#Create a student.