1.4 Inheritance

Introduction

Apart from the relative conceptual simplicity of Object-oriented programming over traditional programming methodologies, OOP also provides a number of technical techniques which enhances the reusability of the code we write, and allows for functionality we would find very difficult to replicate in structured programming. One such technique is that of Inheritance.

Inheritance is the ability to create an object of a class which "inherits" attributes and functions of another class. This allows us to define generic "parent" classes, whose functionality can then be extended and specialized by "children" classes which inherit from the parent.

For example, suppose we are writing software for the real estate industry. We might create a generalized parent class that looks like this:

PROPERTY
-----------------------
property_id
name
description
address
owner_name
owner_telephone
owner_email
selling_price
surface_area
status
-----------------------
print_advert()
mark_sold()
mark_available()

However, we might want specific data to be stored for specific types of property, and thus we might then create child classes such as: apartment, house, duplex, farm, etc... As a further example of what one of these child classes might look at, let's consider the farm child class:

FARM (extends PROPERTY)
-----------------------
plot_number
land_area
farm_type
num_employees
num_buildings
has_dam
has_stables
has_greenhouse
has_orchard
-----------------------

In this example, the farm class, as with the other child classes, will be made up of the attributes and functions of the parent class, as well as the additional attributes and functions of the child class.


Inheritance in Python

The following syntax is used in Python to create a child class which inherits from a parent class:

class ChildClass(ParentClass):
    # Class Definition goes here

So we see here that following the class name, we have the parent class name in brackets.

Note: Python allows multiple inheritance, where you can provide a comma-separated list of parent classes to inherit from. However, please be very careful when doing this, and if you find yourself in a situation where you are about to use multiple inheritance, ask yourself why it is necessary, as you have likely made a design mistake.

Now that we have seen the syntax, let's take a look at a code example:

class Property:

    property_id = 0
    name = ""
    description = ""
    address = ""
    owner_name = ""
    owner_telephone = ""
    owner_email = ""
    selling_price = ""
    surface_area = ""
    status = ""

    def __init__(self):
        self.property_id = 1

    def print_advert(self):
        if self.status == "Available":
            print "Property: P-%d - %s for $%d" % (self.property_id, self.name, self.selling_price)
            print self.description
            print "Surface Area: %s" % (self.surface_area)
            print "Owner: %s (%s)" % (self.owner_name, self.owner_telephone)
            print "Contact the owner at %s" % (self.owner_email)
        else:
            print "Sold!"

    def mark_sold(self):
        self.status = "Sold"

    def mark_available(self):
        self.status = "Available"

class Farm(Property):

    plot_number = ""
    land_area = 0
    farm_type = ""
    num_employees = 0
    num_buildings = 0
    has_dam = False
    has_stables = False
    has_greenhouse = False
    has_orchard = False

# Create Farm
my_farm = Farm()
my_farm.property_id = 1
my_farm.name = "Dairy Queen Farm"
my_farm.description = "A family-run dairy farm with a friendly staff and well cared for cows"
my_farm.selling_price = 1200000
my_farm.surface_area = "20 acres"
my_farm.owner_name = "Henry Ford"
my_farm.owner_telephone = "123456789"
my_farm.owner_email = "henry@ford.com"

# Set as Available
my_farm.mark_available()

# Display Advert
my_farm.print_advert()

In the above code, we create our parent class, Property, and extended it with our specialized Farm child class. We then create a Farm object my_farm and set attributes for the object, and then call the print_advert() function the child class inherited from the parent class.


Accessing Parent attributes and functions

If you need to directly access attributes or functions of the parent class, you can make use of the super() function. This access the "super" class of a child class. The syntax is as follows:

class B(A):
    def method(self, arg):
        super(B, self).method(arg)

Note: Although this is technically viable, it is not recommended to use this technique, as it leads to poorly defined classes.


Visibility

Within classes, certain attributes and functions may be restricted in terms of which other areas of code are able to access them. For example, you might want an attribute of a class to only be accessible from within that class, as it is used for some internal purpose, and not meant for use outside of that class. Or, you might want an attribute or function to only be accessible within a class and its parent/child class. In these situations, we specify the visibility of the attribute or function.

Types of Visibility

There are three types of visibility:

  1. Public: The attribute or function are accessible from inside as well as outside of the class/object.
  2. Private: The attribute or function are only accessible within the class in which it is defined.
  3. Protected: The attribute or function are accessible between classes involved in inheritance, but not outside of that.

Exercise

Write a program which defines a parent company class with a function print_summary() which outputs " | | ", and two children classes: Supplier and Client. Populate one array with Suppliers, and one array with Clients, then loop through each array calling the print_summary() function so you effectively print out a phonebook of clients and suppliers ordered by those groupings.

Continue to next section


Comments

comments powered by Disqus