Search

Object Oriented Programming (OOP) in Python: Inheritance. Part 2

Inheritance as a concept refers to the ability of python child classes to acquire the data attributes and methods of python parent classes. Inheritance occurs many times in programming. We might find two objects that are related but one of the objects has a functionality that is specialized. What we might do is take the common attributes and functions and put them in a class and then take the special attributes and functions and put them in another class, then the objects with the special functions inherit the common attributes and functions.

oop python inheritance

 

For example we have persons and dogs. We know that all persons and dogs are animals with names and they can walk but dogs bark and persons speak words. So the commonality here is being animals. We can create a different animal class for the common features and then create separate dog and person classes for the special features.

The python class which inherits from another python class is called the python child class or derived class while the class from which other classes inherit is called the python parent class or base class.

The syntax for a python class inheritance from a parent class is as stated below:

    
class ChildClassName(ParentClassName):

    statement 1

    statement 2

Let’s take an example from the dog and person objects above. We could create a class for dog objects and another class for person objects and then make the dog and person objects inherit from the animal class since that is their common features. The code could run like the one below:

You can see from the code below that the python child classes, Dog and Person, call the python parent class constructor, Animal.__init__() to initialize their names because name is a common feature for both of them. But Dog and Person have special features like bark and words that they use to talk differently. Also, notice that there is a class variable, legs, for Dog and Person that have different values. This is to emphasize their different legs and these class variables apply to all their objects.

When a derived class definition is executed, it is executed the same way as the parent class and when the python child class is constructed through the __init__() method, the parent class is also remembered. When attribute references are being resolved, the parent class will also be included in the hierarchy of classes to check for such attributes. Just like the self.name calls we had for Dog and Person objects above. When the attribute is not found in the child class, it searches for it in the parent class. The same process occurs for method references. Notice that when I called bingo.talk() and Michael.talk() above, the program first searched the class definitions of the objects to find if there was a talk method defined therein. If there were none, it would have gone on to search the parent classes until the specified method is found.

Another python class inheritance feature you have to notice is that the python child classes in this example override the methods of the python parent classes. This feature is allowed in python class inheritance mechanism. In the example above, the Animal class has a talk and walk method but the child classes also implement a talk and walk method, overriding the talk and walk methods of the parent classes.

You can access the python parent class attributes and functions in a python child class by calling parentclassname.attribute or parentclassname.function. Try it out yourself in code and see. That is what python class inheritance is all about. Child classes own the artefacts of their parents.

Also, another feature you have to notice is that overriding methods may not just want to override the parent methods but they want to extend the parent methods by adding more functionality to what the parent can do. Let me give an example of how python extends classes in inheritance.

You can see that the worker class defines a worker by name and the company he works in. The CEO class inherits from the worker class and also defines the company he works in. But in the works() method, the CEO class calls the works method of Worker using Worker.works(self) and then extends it by printing out that the worker CEO also owns the company. So, you can see how one can extend a method from a child class. You call the method of the parent and add further functionality.

Python functions used to check python class inheritance.

Python has two built-in functions that you can use to check for python class inheritance in your objects. They are isinstance() and issubclass().

isinstance(): The syntax is isinstance(object, classinfo) and it checks if object is an instance of classinfo. That is, it checks for the type of the object. It returns True if object is an instance of classinfo and false otherwise. Examine the code below and run it to see how it works for our inheriting classes.

You will notice that since a dog is a childclass of an animal, it is also an instance of an animal, or it is of type Animal. So, a dog object is an instance (type) of Dog and also an instance (type) of Animal. But a dog is not an instance of a person because it is not inheriting anything from class Person. Please, note these differences.

issubclass(): This function is used to check for python class inheritance. The syntax is issubclass(class, classinfo) where class and classinfo are classes. The function returns True if class is a subclass of classinfo but False otherwise. Let’s use our example classes to check for inheritance.

You will notice that since Dog and Person classes are inheriting from Animal class, they are subclasses of the Animal class but Dog or Person classes are not subclasses because there is no inheritance relationship.

Types of python class inheritance: multilevel inheritance and multiple inheritance.

Python multilevel inheritance: Here we inherit the classes at separate multiple levels. C inherits from B and B inherits from A. For example, consider an example where Person inherits from Animal and Student inherits from Person. If you use isinstance() and issubclass() functions, you can see that Student by this multilevel class inheritance mechanism acquires the data attributes and methods of Animal. Let’s show this with example.

You can see that the Student has a name attribute that is inherited from Animal even though it is directly inheriting from Person, this is because in the inheritance tree it is also inheriting from animal. We show this when we call isinstance() method at the last line.

This is an example of multilevel inheritance.

Python multiple inheritance: In multiple inheritance, a python child class can inherit from more than one python parent class. The syntax for multiple inheritance is:

    
class ChildClass(ParentClass1, ParentClass2, etc):

    statement 1

    statement 2
    

The way python works is that when the object of the child class is searching for an attribute it first looks for it in its own name space, and when not found in that of parentclass1 and in all the parent classes of that class and if it is not found, it then goes to parentclass2 and so on in the order they are written.

Benefits of using python class Inheritance.

Inheritance as an OOP concept has many advantages that it gives to the programmer.

1. It makes the programmer to write less code and to avoid repeating himself. Any code that is written in the parent class is automatically available to the child classes.

2. It also makes for more structured code. When code is divided into classes, the structure of the software is better as each class represents a separate functionality.

3. The code is more scalable.

You can check out my other posts about OOP concepts in python like that about classes and objects, as well as that on python polymorphism.

Happy pythoning.

Object Oriented Programming (OOP) In Python: Classes and Objects Part 1

Computer scientists are continually refining how they write programs. Therefore, they have resorted to several methodologies to do so. Object Oriented Programming (OOP) is a popular methodology and it is the methodology that python relies on. Other programming languages that rely on the OOP methodology include Java and C++.

oop in python class and object

 

Object oriented programming as the name implies relies on objects as its main concept, and along with other related features of objects like classes, inheritance, abstraction and encapsulation. This is a wide departure from functional programming which depend on functions as its main concept. In OOP, every operation is defined as an object and every attribute is based on that owned by the object.

Object oriented programming has become popular because it brings programming close to real life, to the things people could associate with, and not to mathematical functions that are most times the province of professional scientists and mathematicians.

In python, we will start by describing how python implements classes and objects in OOP before we relate it to other features of OOP in python.

Python Class in OOP.

A class is a blueprint for defining data and behavior of objects. It helps us to define similar objects and relate them to a class. For example if you have two dogs, one called “James” and another called “Bingo”, these dogs are both objects with similar behavior and properties. Therefore, we could create a Dog class for both objects.

When we create a python class, we are bringing together the data and behavior of an object and defining them in a bundle. Therefore, creating a new python class is the same thing as creating a new type of object in python and with the ability that new instances of that type can then be made. For example, if we create a Dog class from the example above, new instances of dogs named ‘James’ and ‘Bingo’ can then be made. These class instances are given the attributes defined in the class to maintain their state, and they can also have methods defined by the class for modifying their state.

It is through the python class definition that we can then implement all the features of object oriented programming in python such as class inheritance allowing for multiple child classes, the overriding of the methods of a parent class by a child class, and a child class having methods that have the same name as the parent class. Note that the amount and kinds of data that objects can contain that are derived from a class is unlimited. Just like modules, classes in python are dynamic in nature since they are created at runtime and can be modified after creation.

The following is the syntax of a python class definition:

    
class ClassName:

    statement 1
    statement 2
    

To define a python class you need to use the keyword class to precede the name of the class. Then the name of the class is followed by a colon. The colon delimits the block of statements that represents what goes into a class like the attributes and methods that the class defines for its objects.

Before a python class definition can have any effect, it must be executed like function definitions. The moment you call a python class, you are creating an object, called class instantiation. You can create and call a class this way:

    
# class definition
class Dog:
    
    def method1():
        statement 1...

# class execution. Creates an object
james = Dog()
        
        

When a class is called, a new namespace is formed which includes all the attributes and methods of the class.

Most times when you are instantiating an object or creating an object, you define the instantiation special method, __init__(). This special method contains all the attributes of the object instances that are needed when objects are created. Therefore, when this exists, the moment you invoke the class by creating an object, the object creation process automatically calls the __init__() special method and implements any statement that are contained within the special method.

For example, let’s take a class Animal that specifies that whenever an Animal object is created, it has to be given a name that would be bound to the object. We could write the code with the __init__() special method this way.

    
# class definition
class Animal:
    
    def __init__(self, name):
        ''' name is a string '''
        self.name = name

# class execution. Creates an object
james = Animal('James')

With the code above any Animal object that is created will be supplied a name. Here we gave the animal the name, James. That name is bound to the python object, james, throughout its lifetime and is unique to it.

Python classes also contain data attributes and methods. The data attributes are of two types: data attributes that are generalized for the class and is applicable to all objects (called class variables) and data attributes that are specific to each instance of a class or each object and called instance variables. I will show how class variables are distinguished from instance variables in another section. But note that the ‘name’ attribute for our Animal class above is an instance variable because it pertains to each specific object of the class.

Python class methods are operations that will be performed by the objects of the class. A method is a function that “belongs to” an object. We add the self parameter when defining methods in a class. This tells the python interpreter that the method belongs to the class that called it. But this need not be enforced although many editors will tell you there was an error if you do not insert the self parameter. Let us illustrate an example of an animal that walks and talks below.

Notice that every method of the class has self as the first parameter. The methods walk and talk define what each object of the animal can do.

Python Objects and OOP.

Objects are the physical entities of the world. They serve as a realization of classes which are the logical entitites. An object can be anything – a book, a student, an animal etc. Objects are defined by three important characteristics: (A). An identity or a piece of information that can be used to identify the object e.g name, number. (B). Properties. The attributes of the object. (C). Behavior. These refers to the operations that are done on the object or the functions it can perform. E.g a student can write, a car can move, an animal can walk.

Objects of a python class support two types of operations: attribute reference and instantiation. I have outlined these two operations in the embedded code above but will bring them out again for emphasis.

In python, the standard syntax for attribute references is the dot syntax. In the above code, when referring to the method walk and talk, we used objectname.walk() and objectname.talk(). Also, in the walk and talk methods when referring to the name data attribute we used self.name. Valid attribute names are all the names that are in the class’s namespace when the python object was created following from the class definition.

Class instantiation that creates a python object uses function notation. Class instantiation results in the creation of an object for the class. We denoted class instantiation above with the code: james = Animal(‘James’) where Animal refers to the class Animal. Animal here is being used as a function to create the object james. The class instantiation function can have an argument or no argument based on how you defined your __init__() method. In our __init__() function above we specified that on object creation we need to supply a name for the object.

Python Class and instance variables in OOP.

As we said above, class variables refer to data and methods that are shared by all instances of the class, while instance variables refer to data and methods that are specific and unique to each instance of a class. If you want an attribute to be a class variable, you should not initialize it in the __init__() method but if you want it to be an instance variable you should initialize it in the __init__() special method. Let’s denote these with examples below.

From the example above you can see that we created two Animal objects, james and frog. In the class definition we defined the type attribute outside the __init__() method and therefore when we call it for both objects we have the same value or reply. But we defined the name attribute inside the __init__() method and then when we called the name attribute we received different values for both objects. Always remember this difference between class variables and instance variables in your code so you don’t get code that doesn’t work as you expect when creating classes and objects.

Data Hiding in Python.

In other object oriented programming languages like java they give you the ability to hide data from users getting access to them from outside the class. In this way, they make data private to the class. The makers of python do not want any data hiding in the language implementation. They state that they want everything in python to be transparent. But there are occasions where you can implement data hiding. This can be achieved by prefixing the attribute with a double underscore, __. When this is done you cannot directly access the attribute outside the class.

For example, let’s make the type attribute hidden in the Animal class.

You can see now that to reference the type attribute we get an AttributeError. But there is a workaround that we can use to get the attribute. When you call objectname._Classname__attributename you can get back that attribute. So nothing is hidden in python. Let’s show this with an example. Take note of line 16 in the code below.

It is beneficial to understand how python implements OOP extensively because when you are working in python, you not only use the built in types but have to create your own types. I hope this post helped you along that line. The subsequent posts will treat on other OOP concepts like python class inheritance in OOP and OOP in python - polymorphism that will build on this knowledge. I hope you also enjoy them.

Happy pythoning.

Matched content