Python highly embraces the DRY(Don't Repeat Yourself) principle. It discourages programmers from having duplicate or similar code at various points in the program. The language itself is designed to minimize repetition and increase maintainability.
When defining classes you will likely come across a scenario where one class is just a small alteration of another class. Or one class has features that are similar to another class. Writing each of such classes from scratch will not only be against the DRY principle it will also be inefficient and thus increase the complexity of your code.
Inheritance is a concept in object-oriented programming in which a class inherits or acquires all the attributes and methods of another class. It makes it possible for a class to inherit and build upon the existing attributes and methods of another class instead of re-defining them from scratch. This helps in reducing redundant code and makes the code more organized and efficient.
The class that inherits behavior from another class is known as the derived class, child class or Subclass. The class from which the derived class inherits behavior is known as the base class, parent class or Superclass.
Inheritance in Python classes
Python offers an excellent and intuitive support for class inheritance.
Technically any class in Python uses inheritance this is because all classes are subclasses of the special builtin class named object
.
The builtin issubclass() function checks whether one class is a subclass of another. i.e The class specified as the first argument is a subclass of the class specified as the second argument.
Essentially any Python class will automatically inherit from the class object
when created, so we do not need to state this explicitly. Sometimes, however, we need our classes to inherit features from custom classes. The syntax for achieving this is as shown below:
#Define the baseclass
class BaseClass:
#baseclass body
#define the subclass
class SubClass(BaseClass):
#subclass body
When you do that, all the attributes and methods of the base class are inherited by the derived class.
There is technically no difference between the following classes. It is only that in the first case the inheritance happens under the hood while in the second case we state
explicitly that our class should inherit from the special class, object
class CustomClass:
pass
class CustomClass(object):
pass
Consider the following example.
Note: After a class inherits from another class, we can effectively call the methods and attributes that were inherited.
Alongside the inherited ones, the sub class can define its own unique attributes and methods . In the above example, the subclass, Employee , defines a method is_employee() which doesn't exist in the Parent class.
overriding methods of the super class
A subclass can override a method defined in the superclass by defining another method with the same name. This allows the subclass to provide a different implementation of the same method as that in the superclass, and customize its behavior without changing the behavior of the superclass. Consider the following example:
In the above case, the Employee class effectively overrides get_details method of the parent class.
Extending the methods of the super class- The super() function
In some cases we do not want to entirely override the methods of the superclass. Consider what happens if for example, a sub class defined a method called __init__()
. In this case, the __init__()
method of the subclass will be called instead of the __init__()
method of the superclass.
As shown above, only the child's constructor gets called.
The builtin super() function allows the child class to access the methods and properties of the parent class. The function actually returns the super class itself.
Using the super() function, we can call methods of the super class from the child class. For Example:
To demonstrate the super function better, let us improve our Person and Employee classes.
Multiple Inheritance
Multiple inheritance is where a class inherits from more than one parent class. The definition is that simple, however, the practical implications can get much more complicated.
In multiple inheritance a class inherits all methods from each of the base classes. This can make the code unnecessarily complicated and hard to debug especially if the various base classes have conflicting properties and methods. You should, therefore, avoid multiple inheritance unless you really know what you are doing.
In fact some languages such as Java do not support multiple inheritance to prevent ambiguity.
Extending the Builtin data types
We now have a solid idea on what inheritance involves and how we can use it in Python classes. let us now mess a little bit with the builtin types.
Consider if we want to create a fixed list from the Python list such that if the list has a maximum length. If the maximum length is specified any additional items added to the list causes the list to discard the oldest item.