Implementing Multiple-Inheritance using Python
This tutorial is about the implementation of Multiple-Inheritance in Python, the syntax, program along with an explanation.
Prerequisites: Basic idea of Multiple-Inheritance and implementation of classes in Python (refer: Classes and Objects in Python).
Also read the previous tutorial: Introduction to Multiple Inheritance
The Syntax for Multiple Inheritance
The basic format/syntax for multiple-inheritance in Python is as follows:
class Base_1: #Base Class 1 pass class Base_2: #Base Class 2 pass class Derived(Base_1,Base_2): #Class that derives from both the above base classes pass
The above code contains two base classes. Both of them may have their member functions and data members. The third class, which derives from both these base classes can make use of their data members as well as member functions, as long as they are not private to the respective base classes.
Sample Program for Multiple Inheritance
Now, we take up an example to make things more clear. Consider cricket players. There are broadly three categories – batsmen, bowlers and all-rounders. All-rounders have statistical data records about both batting as well as bowling. In other words, they inherit the characteristics of both categories – batsmen and bowlers.
Section-wise explanation
Let us first define the base classes
class Batsman: def __init__(self): self.strike_rate = 0.0 self.total_runs = 0 self.highest_score = 0 self.batting_rank = 0 def get_bat(self,sr,tr,hs,br): self.strike_rate = sr self.total_runs = tr self.highest_score = hs self.batting_rank = br def disp_bat(self): print "Strike Rate:",self.strike_rate print "Total Runs:",self.total_runs print "Highest Score:",self.highest_score print "Batting Rank:",self.batting_rank
This is the Batsman class, which contains identifiers for some of the details about a batsman and two member functions: get_bat – to get the details of an object of batsman class, and disp_bat – to display the details of an object of the batsman class.
In the same way, we define another base class – Bowler with details and functions relating to a bowler.
class Bowler: def __init__(self): self.wickets_taken = 0 self.economy = 0.0 self.hattricks = 0 self.bowling_rank = 0 def get_bowl(self,wt,ec,ht,bor): self.wickets_taken = wt self.economy = wc self.hattricks = ht self.bowling_rank = bor def disp_bowl(self): print "Wickets Taken:",self.wickets_taken print "Economy:",self.economy print "Hattricks:",self.hattricks print "Bowling Rank:",self.bowling_rank
So, now that we have both our base classes, we define the derived class
class AllRounder(Batsman,Bowler): def __init__(self): Batsman.__init__(self) Bowler.__init__(self) self.allrounder_rank = 0 def get_all(self,sr,tr,hs,br,wt,ec,ht,bor,ar): Batsman.get_bat(self,sr,tr,hs,br) Bowler.get_bowl(self,wt,ec,ht,bor) self.allrounder_rank = def disp_all(self): self.disp_bat() self.disp_bowl() print "All Rounder Rank:",self.allrounder_rank
As per the syntax, the names of the base classes have been mentioned within parentheses, soon after the name of the class in the class header line
In this class, under the __init__() function, we have explicitly called the __init__ functions of the base classes, so that whenever an object of class -AllRounder is initialised, the instance variables of the base classes for the object will also get initialised. Suppose we create an object – obj of AllRounder, the __init__ method of class AllRounder will be called implicitly, following which, the inherited data members of obj from Batsman and Bowler classes will be initialised when the explicit calls are made to their __init__functions.
After that, we add an allrounder_rank data member. This is specific only to objects of AllRounder class and holds no meaning for objects of Batsman or Bowler class. In this way, we can add specific features to the derived class, without disturbing the base classes.
Similarly, in the get_all and disp_all functions, assign/display data values that belong the base classes by calling the respective inherited member functions, as well as, the ones that are specific to the derived AllRounder class.
Complete Program
Let us now put together the pieces and create an object of the AllRounder class.
class Batsman: def __init__(self): self.strike_rate = 0.0 self.total_runs = 0 self.highest_score = 0 self.batting_rank = 0 def get_bat(self,sr,tr,hs,br): self.strike_rate = sr self.total_runs = tr self.highest_score = hs self.batting_rank = br def disp_bat(self): print "\nBATTING DATA\n" print "Strike Rate:",self.strike_rate print "Total Runs:",self.total_runs print "Highest Score:",self.highest_score print "Batting Rank:",self.batting_rank class Bowler: def __init__(self): self.wickets_taken = 0 self.economy = 0.0 self.hattricks = 0 self.bowling_rank = 0 def get_bowl(self,wt,ec,ht,bor): self.wickets_taken = wt self.economy = ec self.hattricks = ht self.bowling_rank = bor def disp_bowl(self): print "\nBOWLING DATA\n" print "Wickets Taken:",self.wickets_taken print "Economy:",self.economy print "Hattricks:",self.hattricks print "Bowling Rank:",self.bowling_rank class AllRounder(Batsman,Bowler): def __init__(self): Batsman.__init__(self) Bowler.__init__(self) self.allrounder_rank = 0 def get_all(self,sr,tr,hs,br,wt,ec,ht,bor,ar): Batsman.get_bat(self,sr,tr,hs,br) Bowler.get_bowl(self,wt,ec,ht,bor) self.allrounder_rank = ar def disp_all(self): print "\nALL-ROUNDER DATA" print "\nAll-Rounder Rank:",self.allrounder_rank self.disp_bat() self.disp_bowl() player1 = AllRounder() player1.get_all(89.7,3024,96,67,101,5.67,4,34,57) player1.disp_all()
In the main section, we declare player1 as an object of the AllRounder class. We then accept all data values for player1 through the get_all function. Redistribute them to respective base classes (see the function definition). Finally, we display the data for the player1 object.
The output is as follows
Leave a Reply