12.5 Understanding Inheritance

To better understand how inheritance works, we can look behind the scenes at how Python keeps track of instance variables and methods. Each class and instance of a class has some special instance variables that we can use to see how Python finds the right method to call or the right instance variable.

First, the _ _bases_ _ instance variable tells us the names of the superclass of any class. For example, in SESSION 12.3, you can see that the superclass of Line is GeometricObject. The parent of GeometricObject is ABC (Abstract Base Class). The parent of ABC is object, and object has no parent. This succession of child-to-parent links is very important for Python when a method is called that was defined in a parent class. By default, Python uses the special class object at the top of the inheritance hierarchy.

Image

SESSION 12.3 Investigating the inheritance hierarchy

The name _ _bases_ _ comes from the term base class, which is an alternative way of thinking about the superclass–subclass relationship. Some programmers say that the superclass is the base class, and the subclass extends the base class. In our hierarchy, GeometricObject is the base class of the Line class. The critical idea is that Line has all the functionality of GeometricObject plus new functionality that extends the base class.

Another instance variable that each class maintains is the _ _dict_ _ variable. This instance variable is a dictionary that keeps track of the methods defined for the class. For example, in Session 12.3 you can see that the dictionary of methods for the Line class has keys that correspond to the name of every method we defined.

Instances of Python objects also have some special instance variables. Every object has an instance variable called _ _class_ _, which contains a reference to the object’s class. In Session 12.3, you can see that myLine._ _class_ _ refers to the Line class. In addition, the _ _dict_ _ variable for instances of classes contains a dictionary of user-defined instance variables. For example, Session 12.3 shows that an instance of the Line class also has a _ _dict_ _ instance variable that contains keys for _ _lineColor and _ _lineWidth that are inherited from the GeometricObject class as well as _ _p1 and _ _p2 defined in the Line class.

Putting all these special variables together, we can see in more detail how inheritance works in Python. FIGURE 12.5 shows a reference diagram that illustrates the chain of events in the Python interpreter for the expression myLine.getWidth().

A diagram denotes the flow of events for the expressions myLine.getWidth().

FIGURE 12.5 A reference diagram for following an inheritance chain. The numbered arrows indicate the order of the search operation.

  1. When Python evaluates the expression myLine.getWidth(), the first step is to dereference the name myLine—that is, to find the object in memory. Python next tries to dereference the name getWidth using the following chain of lookups.

  2. If _ _dict_ _ in myLine contains getWidth as a key, stop searching and use it.

  3. The method is not in myLine, so follow the _ _class_ _ link to the Line class.

  4. If _ _dict_ _ in the Line class contains getWidth as a key, stop searching and use it.

  5. The method is not in Line, so follow the _ _bases_ _ link to the superclass (GeometricObject).

  6. If _ _dict_ _ contains getWidth as a key, stop searching and use it.

  7. In this case, we do find the getWidth method in the GeometricObject class.

Steps 5 and 6 can be repeated until all of the classes listed in _ _bases_ _ have been tried. If all base classes are exhausted and getWidth is not found, then generate an error.

Once the name getWidth is dereferenced, the next step is to apply the function call operators (). Since we are applying the call operators to a method of a class, we take the value of myLine and pass it as the first parameter to the getWidth function. In the getWidth function, myLine is called self. FIGURE 12.6 illustrates the binding of myLine as an actual parameter to the formal parameter self. The main thing to notice is that myLine and self both reference the same instance of a Line.

An illustration of the self parameter.

FIGURE 12.6 The self parameter with an inherited method.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.16.135.67