Python Intermediate
title
Chapter-2 Inheritance
2.1 Inherting classes in Python
In [5]: class Person:
def __init__(self,name,age):
self.name = name
self.age = age
def display(self):
print('Name:',self.name)
print('Age:', self.age)
class Teacher(Person):
def __init__(self,name,age,exp,r_area):
Person.__init__(self,name,age)
self.exp = exp
self.r_area = r_area
def display_data(self):
Person.display(self)
print("Experience:",self.exp)
print("Research Area:",self.r_area)
t1 = Teacher('Ashish Nandre', 36, 10, 'Machine Learning')
t1.display_data()
Name: Ashish Nandre
Age: 36
Experience: 10
Research Area: Machine Learning
In [1]: class Account:
def __init__(self, account_number, balance):
self.account_number = account_number
self.balance = balance
def deposit(self, amount):
self.balance += amount
print("Deposit successful. New balance:", self.balance)
def withdraw(self, amount):
if self.balance >= amount:
self.balance -= amount
print("Withdrawal successful. New balance:", self.balance)
else:
print("Insufficient funds.")
class SavingsAccount(Account):
def __init__(self, account_number, balance, interest_rate):
Account.__init__(self,account_number, balance)
self.interest_rate = interest_rate
def calculate_interest(self):
interest = self.balance * self.interest_rate
self.deposit(interest)
print("Interest added. New balance:", self.balance)
class CurrentAccount(Account):
def __init__(self, account_number, balance, overdraft_limit):
Account.__init__(self,account_number, balance)
self.overdraft_limit = overdraft_limit
def withdraw(self, amount):
if self.balance + self.overdraft_limit >= amount:
self.balance -= amount
print("Withdrawal successful. New balance:", self.balance)
else:
print("Insufficient funds. You have exceeded your overdraft limit.")
# Example usage:
savings_acc = SavingsAccount("SA123", 1000, 0.05)
savings_acc.deposit(500)
savings_acc.calculate_interest()
checking_acc = CurrentAccount("CA456", 2000, 500)
checking_acc.withdraw(2500)
checking_acc.withdraw(1500)
Deposit successful. New balance: 1500
Deposit successful. New balance: 1575.0
Interest added. New balance: 1575.0
Withdrawal successful. New balance: -500
Insufficient funds. You have exceeded your overdraft limit.
Multiple Inheritance
In [2]: class Base1:
def method1(self):
print("Method 1 from Base1")
class Base2:
def method2(self):
print("Method 2 from Base2")
class MyClass(Base1, Base2):
pass
obj = MyClass()
obj.method1() # Output: Method 1 from Base1
obj.method2() # Output: Method 2 from Base2
Method 1 from Base1
Method 2 from Base2
However, multiple inheritance can lead to complexities and is sometimes
discouraged due to potential conflicts in method names and inheritance
order dependencies. To manage these issues, Python follows a specific
order when searching for methods and attributes in multiple inheritance
scenarios. This order is determined by the "Method Resolution Order"
(MRO), which you can access using the mro attribute or the mro() method.
In [1]: class A:
def method(self):
print("A method")
class B(A):
def method(self):
print("B method")
class C(A):
def method(self):
print("C method")
class D(B, C):
pass
# Output the Method Resolution Order
print(D.mro())
[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.
A'>, <class 'object'>]
In this example, the MRO of class D will be [D, B, C, A, object]. When you
call D().method(), Python will first look for the method() implementation in
class D, then in B, then in C, then in A, and finally in the base class object.
This is the order in which the methods will be resolved and executed.
TYPES
1.Multi-level inheritance
The technique of deriving a class from an already derived class is called
multilevel inheritance
2. Multipath Inheritance
Deriving a class from other derived classes from same base class is called
multipath inheritance
2.2 Polymorphism and Method overriding
Polymorphism:- Several Different Form
Method Overriding:- To change the implementation of a method in
ancestore class.
Example-1 Write a program that has as abstract class polygon. Derive two
classes Rectangle and Triangle from polygon and write methods to get
their details of dimensions and hence calculate area.
In [9]: class Polygon:
def get_data(self):
raise NotImplementedError
def area(self):
raise NotImplementedError
class Rectangle(Polygon):
def get_data(self): # Method Overriding
self.length = int(input('Enter length:'))
self.breadth = int(input('Enter breadth:'))
def area(self):# Method Overriding
self.area = self.length*self.breadth
return self.area
class Triangle(Polygon):
def get_data(self):
self.base = int(input('Enter base:'))
self.height = int(input('Enter height:'))
def area(self):
return 0.5 * self.base *self.height
r1 = Rectangle()
r1.get_data()
print("Area:",r1.area())
t1 = Triangle()
t1.get_data()
print("Area:",t1.area())
p1 = Polygon()
p1.get_data()
p1.area()
Area: 6
Area: 1.0
---------------------------------------------------------------------------
NotImplementedError Traceback (most recent call last)
Cell In[9], line 31
28 print("Area:",t1.area())
30 p1 = Polygon()
---> 31 p1.get_data()
32 p1.area()
Cell In[9], line 3, in Polygon.get_data(self)
2 def get_data(self):
----> 3 raise NotImplementedError
NotImplementedError:
In [11]: class Account:
def __init__(self, account_number, balance):
self.account_number = account_number
self.balance = balance
def deposit(self, amount):
self.balance += amount
print("Deposit successful. New balance:", self.balance)
def withdraw(self, amount):
if self.balance >= amount:
self.balance -= amount
print("Withdrawal successful. New balance:", self.balance)
else:
print("Insufficient funds.")
class SavingsAccount(Account):
def __init__(self, account_number, balance, interest_rate):
super().__init__(account_number, balance)
self.interest_rate = interest_rate
def calculate_interest(self):
interest = self.balance * self.interest_rate
self.deposit(interest)
print("Interest added. New balance:", self.balance)
class CurrentAccount(Account):
def __init__(self, account_number, balance, overdraft_limit):
super().__init__(account_number, balance)
self.overdraft_limit = overdraft_limit
def withdraw(self, amount):
if self.balance + self.overdraft_limit >= amount:
self.balance -= amount
print("Withdrawal successful. New balance:", self.balance)
else:
print("Insufficient funds. You have exceeded your overdraft limit.")
# Function to demonstrate polymorphism
def perform_transaction(account, amount):
account.withdraw(amount)
# Example usage:
savings_acc = SavingsAccount("SA123", 1000, 0.05)
current_acc = CurrentAccount("CA456", 2000, 500)
# Using polymorphism in action
perform_transaction(savings_acc, 200)
perform_transaction(current_acc, 500)
Withdrawal successful. New balance: 800
Withdrawal successful. New balance: 1500
In [ ]: