Wednesday, November 14, 2018

Inheritance

Inheritance allows us to inherit methods and attributes of the parent class. By inheritance, a new child class automatically gets all of the methods and attributes of the existing parent class. The syntax is given as follows:

class DerivedClassName(BaseClassName):
<statement-1>
.
. .
<statement-N>

We already created an Employee class in our previous posts but in case you couldn't recall here is the code -

class Employee():
   
    def __init__(self,position):
       
        self.position = position
   
    def setPosition(self):
        self.position= position


    def getPosition(self):
        return self.position.title()


emp1 = Employee('tester')
emp2 = Employee('developer')


print(emp1.getPosition())
print(emp2.getPosition())


Assuming you have understood Python classes, you should be able to understand the functionality of this class. Here Employee class is my parent class. To see how inheritance works i'll create a child class newEmployee which will simply inherit the Employee class and doesn't add any new functionality of it's own. This is the code for newEmployee class -

class newEmployee(Employee):
   
    pass


The complete program is shown below -

class Employee():
   
    def __init__(self,position):
       
        self.position = position
   
    def setPosition(self):
        self.position= position


    def getPosition(self):
        return self.position.title()
       
class newEmployee(Employee):
   
    pass       
   
emp1 = Employee('tester')
emp2 = Employee('developer')

print("\nEmployees created from Parent class\n")
print(emp1.getPosition())
print(emp2.getPosition())

new_emp1 = newEmployee('accountant')
new_emp2 = newEmployee('HR Manager')

print("\nNew employees created from child class\n")
print(new_emp1.getPosition())
print(new_emp2.getPosition())


Here are few significant points to be noted for creating inheritance -

1. When you create a child class, the parent class must be part of the current file and must appear     before the child class in the file. Thus Employee class is written first in the program then new Employee class is written.

2. The name of the parent class must be included in parentheses in the definition of the child class. Thus we have written class newEmployee(Employee) which indicates we are creating a child class newEmployee from parent class Employee.

To test whether inheritance is working properly, create employees using both parent class and child class. When we run the program we get the following output -



In the child class we didn't define any getPosition() since it was already defined in the parent class. Using a child class object we accessed the getPosition() of parent class and printed the desired result.

Let's change our child class so that it add it's own behavior, create and print email Id of the employee it created. See the modified code below -

class newEmployee(Employee):
  
    def __init__(self,position,fname,lname):
      
        super().__init__(position)
      
        self.fname = fname
        self.lname = lname
  
    def createEmailId(self):
      
        return self.fname + "." + self.lname + "@covrisolutions.com"


The __init__() method  takes in the information required to make an Employee instance. The super() function is a special function that helps Python make connections between the parent and child class. This line tells Python to call the __init__() method from newEmployee’s parent class, which gives an
newEmployee instance all the attributes of its parent class.

Our new program is now as shown below -

class Employee():
   
    def __init__(self,position):
       
        self.position = position
   
    def setPosition(self):
        self.position= position


    def getPosition(self):
        return self.position.title()
       
class newEmployee(Employee):
   
    def __init__(self,position,fname,lname):
       
        super().__init__(position)
       
        self.fname = fname
        self.lname = lname
   
    def createEmailId(self):
       
        return self.fname + "." + self.lname + "@covrisolutions.com"
       
               
   
emp1 = Employee('tester')
emp2 = Employee('developer')

print("\nEmployees created from Parent class\n")
print(emp1.getPosition())
print(emp2.getPosition())

new_emp1 = newEmployee('accountant','Clare','Gong')
new_emp2 = newEmployee('HR Manager','Wendy','Wang')

print("\nNew employees created from child class\n")
print(new_emp1.getPosition())
print(new_emp2.getPosition())

print("\nEmail Ids of employees created from child class\n")
print(new_emp1.createEmailId())
print(new_emp2.createEmailId())



The output of this program is shown below -




Try to run the program after removing super().__init__(position) from the code. Also try to access createEmailId() using Employee class object.

We have seen that a child class can add it's own attributes and methods. It is also possible for a child class to override it's parent class's method. Let's override the getPosition() of the Employee class in newEmployee class. The original getPosition() is -

def getPosition(self):
        return self.position.title()




The overridden version is as follows -

def getPosition(self):
        return self.fname + "'s " + "position is " +self.position.title()


Here we are printing the created employee's name and position both. The modified code is shown below -

class Employee():
   
    def __init__(self,position):
       
        self.position = position
   
    def setPosition(self):
        self.position= position


    def getPosition(self):
        return self.position.title()
       
class newEmployee(Employee):
   
    def __init__(self,position,fname,lname):
       
        super().__init__(position)
       
        self.fname = fname
        self.lname = lname
   
    def createEmailId(self):
       
        return self.fname + "." + self.lname + "@covrisolutions.com"
       
    def getPosition(self):
        return self.fname + "'s " + "position is " +self.position.title()           
   
emp1 = Employee('tester')
emp2 = Employee('developer')

print("\nEmployees created from Parent class\n")
print(emp1.getPosition())
print(emp2.getPosition())

new_emp1 = newEmployee('accountant','Clare','Gong')
new_emp2 = newEmployee('HR Manager','Wendy','Wang')

print("\nNew employees created from child class\n")
print(new_emp1.getPosition())
print(new_emp2.getPosition())

print("\nEmail Ids of employees created from child class\n")
print(new_emp1.createEmailId())
print(new_emp2.createEmailId())

The output of this program is shown below -



It is possible to call the parent class getPosition() using a child class object. So that both versions of the getPosition() can be used in the program. We will create an attribute self.emp is the newEmployee class which tells Python to create a new instance of Employee class. See the code below -

class newEmployee(Employee):
   
    def __init__(self,position,fname,lname):
       
        super().__init__(position)
        self.emp = Employee(position)
        self.fname = fname
        self.lname = lname
   
    def createEmailId(self):
       
        return self.fname + "." + self.lname + "@covrisolutions.com"
       
    def getPosition(self):
        return self.fname + "'s " + "position is " +self.position.title()   



The line self.emp = Employee(position) tells Python to create a new instance of Employee class and store that instance in the attribute self.emp. This will happen every time the __init__() method is called; any newEmployee instance will now have a Employee instance created automatically. Now when we want to call the parent class getPosition() we will use the child and parent class objects as follows -

new_emp1.emp.getPosition()
new_emp2.emp.getPosition() 

These lines tells Python to look at the instances new_emp1/new_emp2, find its emp attribute, and call the method getPosition() that’s associated with the Employee instance stored in the attribute.The complete program is shown below -


class Employee():
   
    def __init__(self,position):
       
        self.position = position
   
    def setPosition(self):
        self.position= position


    def getPosition(self):
        return self.position.title()
       
class newEmployee(Employee):
   
    def __init__(self,position,fname,lname):
       
        super().__init__(position)
        self.emp = Employee(position)
        self.fname = fname
        self.lname = lname
   
    def createEmailId(self):
       
        return self.fname + "." + self.lname + "@covrisolutions.com"
       
    def getPosition(self):
        return self.fname + "'s " + "position is " +self.position.title()           
   
emp1 = Employee('tester')
emp2 = Employee('developer')

print("\nEmployees created from Parent class\n")
print(emp1.getPosition())
print(emp2.getPosition())

new_emp1 = newEmployee('accountant','Clare','Gong')
new_emp2 = newEmployee('HR Manager','Wendy','Wang')

print("\nNew employees created from child class\n")
print(new_emp1.getPosition())
print(new_emp2.getPosition())

print("\nNew employees created from Parent class method\n")
print(new_emp1.emp.getPosition())
print(new_emp2.emp.getPosition())

print("\nEmail Ids of employees created from child class\n")
print(new_emp1.createEmailId())
print(new_emp2.createEmailId())


The output of this program is shown below -



This is how inheritance works in Python. In the next post we shall discuss about types of inheritance and operator overloading. Until then keep practicing and learning Python as Python is easy to learn!






Share:

0 comments:

Post a Comment