Classes and inheritance¶
Inheritance in Python is simpler and more flexible than inheritance in compiled languages such as Java and C++ because the dynamic nature of Python does not impose as many restrictions on the language.
To see how inheritance is used in Python, let’s start with the Square and
Circle classes we discussed earlier and generalise them.
If we now want to use these classes in a drawing program, we need to define
where on the drawing surface an instance should be located. We can do this by
defining x and y coordinates for each instance:
 1>>> class Square:
 2...     def __init__(self, length=1, x=0, y=0):
 3...         self.length = length
 4...         self.x = x
 5...         self.y = y
 6...
 7>>> class Circle:
 8...     def __init__(self, diameter=1, x=0, y=0):
 9...         self.diameter = diameter
10...         self.x = x
11...         self.y = y
12...
This approach works, but leads to a lot of repetitive code when you increase the
number of shape classes, as you probably want every shape to have this
positional information. This is a standard situation for using inheritance in
object-oriented languages. Instead of defining the x and y variables in
each shape class, you can abstract them into a general shape class and have each
class that defines a particular shape inherit from that general class. In
Python, this technique looks like this:
 1>>> class Form:
 2...     def __init__(self, x, y):
 3...         self.x = x
 4...         self.y = y
 5...
 6>>> class Square(Form):
 7...     def __init__(self, length=1, x=0, y=0):
 8...         super().__init__(x, y)
 9...         self.length = length
10...
11>>> class Circle(Form):
12...     def __init__(self, diameter=1, x=0, y=0):
13...         super().__init__(x, y)
14...         self.diameter = diameter
15...
- Lines 6 and 11
- Squareand- Circleinherit from the- Formclass.
- Lines 8 and 13
- call the - __init__method of the- Formclass.
There are generally two requirements when using an inherited class in Python,
both of which you can see in the code of the Circle and Square classes:
- The first requirement is to define the inheritance hierarchy, which you do by specifying the classes that are inherited from in parentheses immediately after the name of the class, which is defined with the class keyword: - Circleand- Squareboth inherit from- Form.
- The second element is the explicit call to the - __init__method of the inherited class. This is not done automatically in Python, but mostly through the- superfunction, more precisely through the lines- super().__init__(x,y). This code calls the initialisation function of- Formwith the instance to be initialised and the corresponding arguments. Otherwise, the instance variables- xand- ywould not be set for the instances of- Circleand- Square.
Inheritance also comes into play when you try to use a method that is not
defined in the base classes but in the superclass. To see this effect, define
another method in the Form class called move that moves a shape in the
x and y coordinates. The definition for Form is now:
1>>> class Form:
2...     def __init__(self, x=0, y=0):
3...         self.x = x
4...         self.y = y
5...     def move(self, delta_x, delta_y):
6...         self.x = self.x + delta_x
7...         self.y = self.y + delta_y
8...
If you take the parameters delta_x and delta_y of
the method move in the __init__ methods of Circle and Square,
you can for example execute the following interactive session:
>>> c = Circle(3)
>>> c.move(4, 5)
>>> c.x
4
>>> c.y
5
The class Circle in the example does not have a move method defined
directly in itself, but since it inherits from a class that implements move,
all instances of Circle can use the move method. In OOP terms, one could
say that all Python methods are virtual – that is if a method does not exist in
the current class, the list of superclasses is searched for the method and the
first one found is used.
Checks¶
- Rewrites the code for a - Triangleclass so that it inherits from- Form.
- How would you write the code to add an - area()method for the- Triangleclass? Should the- area()method be moved to the- Formbase class and inherited by- Circle,- Squareand- Triangle? What problems would this change cause?