Make App Pie

Training for Developers and Artists

From Apple to Raspberry Pi: Using Inheritance and Overrides

appleberry

Object oriented languages have a  concept called inhertance. A class can give its methods and properties to another class, which then replaces or expands the inherited class. We call the new class a subclass. When we replace a function or method we override the method or function. This allows the method or function of the same name to work in many circumstances. Let’s look at some Objective C- code.

#import "PDPythonStuff.h"

@implementation PDPythonStuff

-(int)montyFunction:(int)a b:(int)b{
     return a+b*b;
}
-(int)montyFunction{
     return self.a+self.b*self.b;
}

@end

We  have a different number of parameters in each method for this to work. We cannot, however add this method with different types to the implementation above:

-(float)montyFunction:(float)a b:(float)b{
     return a+b*b;
}

To use this code, I need  a subclass. I  define a subclass  in my header file:

@interface PDPythonFloatStuff :<strong> PDPythonStuff</strong>
     -(float)montyFunction:(float)a b:(float)b;
     -(float)montyFunction;
@end

I then override the methods above by re-writing them for floating point numbers.

@implementation PDPythonFloatStuff
-(float)montyFunction:(float)a b:(float)b{
    return a+b*b;
}
-(float)montyFunction{
    return self.a+self.b*self.b;
}
@end

Now let’s look at Python and inheritance. Look at this code.

#PSPythonStuff.py
class PSPythonStuff:
    def __init__(self,a,b):
        self.a = a
        self.b = b
    def montyPythonFunction(self,a,b):
        return a+b*b
    def montyPythonFunction(self):
        return self.a + self.b * self.b

We have two functions with the same name but a different number of parameters. Run the code, it runs successfully, though nothing seems to  happen. Now at the Shell, type the following:

>>> from PSPythonStuff import *
>>> my_instance = PSPythonStuff(5,25)
>>> print(my_instance.montyPythonFunction())

The shell responds with

630

One function works. Now try the other function:

>>> print(my_instance.montyPythonFunction(5,25))

We get an error:

Traceback (most recent call last):
File "<pyshell#3>", line 1, in;
print(my_instance.montyPythonFunction(5,25))
TypeError: montyPythonFunction() takes 1 positional argument but 3 were given

The message tells us that only the montyPython() function exists. Unlike Objective-C, we cannot have two functions with the same name but different parameters. The last one defined is the only function that works.

Using inheritance, We can define subclasses from the parent class or the super class. The subclass has everything that the super class does, but we  customize the subclass. We override same function or method from one class in a subclass as we did in Objective-C. Now if we want to use our function, we can.
Let’s define a class PSMorePythonStuff in Python which is a subclass of PSPythonStuff.

#PSPythonStuff.py
class PSPythonStuff:
    def __init__(self,a,b):
        self.a = a
        self.b = b
    def montyPythonFunction(self,a,b):
        return a+b*b

class PSMorePythonStuff(PSPythonStuff):
    def __init__(self,a,b):
        PSPythonStuff.__init__(self,a,b)
    def montyPythonFunction(self):
        return self.a+self.b*self.b

We tell Python this is a subclass by placing in parentheses the superclass PSPythonStuff.  In __init__ we add

PSPythonStuff.__init__(self,a,b)

This initializes and further connects the attributes of the super class to the subclass. Note here we use all three parameters for __init__ so that self connects the subclass and super class. Now open a new window and type the following module:

#class_demo_3
from PSPythonStuff import *
my_instance = PSPythonStuff(5,25)
print(my_instance.montyPythonFunction(5,25))
my_other_instance = PSMorePythonStuff(5,25)
print (my_other_instance.montyPythonFunction())

Save both modules and run class_demo_3. Because they are different classes, the montyPythonFunction works with different parameters.

We can also add attributes. Let’s make another subclass of PSPythonStuff. At the bottom of PSPythonStuff.py add

class PSStillMorePythonStuff(PSPythonStuff):
    def __init__(self,a,b,c):
        PSPythonStuff.__init__(self ,a,b)
        self.c=c
    def montyPythonFunction(self):
        return self.a+self.b*self.c
    def printMontyPythonFunction(self,myString):
        print(myString,self.a,self.b,self.c, self.montyPythonFunction())

add to class_demo_3

another_instance = PSStillMorePythonStuff(1,2,3)
print(another_instance.montyPythonFunction())
another_instance.printMontyPythonFunction('hello')

Save and run. Our code works. Most of object-oriented programming is subclassing and overriding what already exists. There is a special case of inheritance, known as an abstract class. Next time, we’ll talk about the abstract class pattern.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: