0% found this document useful (0 votes)
42 views

Unit 3

Uploaded by

Chinnu Reddy
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
42 views

Unit 3

Uploaded by

Chinnu Reddy
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 71

OO Approach in Python

1
Object Oriented Features

• Classes and Objects


• Encapsulation
• Abstraction
• Inheritance
• Polymorphism

2
Classes and Objects
class Classname(object): # or class Classname:
""" docstring describing the Class """
attributes
def __init__(self):
def method1():
def method2():

instancename = Classname()

3
_init_()
• The __init__() function is a special method to initialize the variables
• The __init__() function is called automatically every time the class is being
used to create a new object.
• The self parameter is a reference to the class instance itself, and is used to
access variables that belongs to the class.
• ‘self’ is a variable that contains the memory address of the instance of the
current class.
• It does not have to be named self , you can call it whatever you like, but it
has to be the first parameter of any function in the class

4
Example
class Employee:
def __init__(self, name, age): # Constructor
self.name = name
self.age = age

def empdetails(self):
print("Employee name is " + self.name)
print("Employee age is " , self.age)

e1 = Employee("John",40)
e1. empdetails()

5
Example
class Employee:
def __init__(self, name= "xyz", age=30):
self.name = name
self.age = age

def myfunc(self):
print("Employee name is "+ self.name)
print("Employee age is " , self.age)

e1 = Employee("John",40) Note: No Overloading of Constructor


e1.myfunc()
print() Output
e2=Employee() Employee name is John
e2.myfunc() Employee age is 40

Employee name is xyz


Employee age is 30
6
Types of Variables
 Instance Variables
 These are variables whose separate copy is created in every
instance(or object)
 Defined and initialized using a constructor with ‘self’ parameter.
 To access instance variables, we need instance methods with ‘self’ as
first parameter.
 To access instance variables, we use self.variable

 Class Variables or Static Variables


 These are the variables whose single copy is available to all the
instances of the class.
 Also called as Static variables
 If we modify the copy of class variable in an instance, it will modify all
the copies in the other instances.

7
Example: Instance Variable
class Sample:
def __init__(self): Output
self.x=10 x in S1= 10
def modify(self): x in S2= 10
x in S1= 11
self.x+=1
x in S2= 10

s1 = Sample()
s2 = Sample()
print('x in S1= ',s1.x)
print('x in S2= ',s2.x)
s1.modify()
print('x in S1= ',s1.x)
print('x in S2= ',s2.x) 8
Example: Class / Static Variable
class Sample:
x = 10 Output
x in S1= 10
@classmethod # built-in decorator statement x in S2= 10
def modify(cls): x in S1= 11
cls.x+=1 x in S2= 11
x Value= 11
s1 = Sample()
s2 = Sample()
print('x in S1= ',s1.x)
print('x in S2= ',s2.x)
s1.modify()
print('x in S1= ',s1.x)
print('x in S2= ',s2.x)
print('x Value= ',Sample.x)
9
Example : Class Variables
class Employee: print("Number of employees before creating
totemps = 0 Instances:", Employee.totemps)
payhike= 1.04 emp_1 = Employee('Rishi',70000)
def __init__(self,name,pay): emp_2 = Employee('Shwetha',80000)
self.name= name print("Number of employees after creating
self.pay = pay Instances:",Employee.totemps)
Employee. totemps +=1 print ("Pay of Employee 1:",emp_1.pay)
def apply_hike(self): print ("Pay of Employee 2:",emp_2.pay)
self.pay = int(self.pay * self.payhike) emp_1.apply_hike ()
emp_2.apply_hike()
print ("Pay of Employee 1 after hike:",emp_1.pay)
print ("Pay of Employee 1 after hike:",emp_2.pay)
Output
Number of employees before creating Instances: 0
Number of employees after creating Instances: 2
Pay of Employee 1: 70000
Pay of Employee 2: 80000
Pay of Employee 1 after hike: 72800
Pay of Employee 1 after hike: 83200 10
Example : Class Variables
class Employee: print("Number of employees before creating
totemps = 0 Instances:", Employee.totemps)
payhike= 1.04 emp_1 = Employee('Rishi',70000)
def __init__(self,name,pay): emp_2 = Employee('Shwetha',80000)
self.name= name print("Number of employees after creating
self.pay = pay Instances:",Employee.totemps)
Employee. totemps +=1 print ("Pay of Employee 1:",emp_1.pay)
def apply_hike(self): print ("Pay of Employee 2:",emp_2.pay)
self.pay = int(self.pay * emp_1.apply_hike ()
Employee.payhike) emp_2.apply_hike()
print ("Pay of Employee 1 after hike:",emp_1.pay)
print ("Pay of Employee 1 after hike:",emp_2.pay)

Output
Number of employees before creating Instances: 0
Number of employees after creating Instances: 2
Pay of Employee 1: 70000
Pay of Employee 2: 80000
Pay of Employee 1 after hike: 72800
Pay of Employee 1 after hike: 83200 11
Namespaces
• Represents a memory block where names are mapped (or linked)
to objects
• A class maintains its own namespace, called ‘class namespace’
• In class namespace, the names are mapped to class variables.
• Every instance will have its own name space, called ‘instance
namespace’
• In instance namespace, the names are mapped to instance
variables.

12
Example - Namespace
class Student: Class Namespace
mks=10 mks 10

print(Student.mks)
Student.mks+=5
print(Student.mks)
s1=Student()
print(s1.mks) mks 10 mks 10
s2=Student() Instance Namespace of S1 Instance Namespace of S2
print(s2.mks)
Class Namespace
mks 15

mks 15 mks 15

Instance Namespace of S1 Instance Namespace of S2 13


Example - Namespace
class Student: Class Namespace
mks=10 mks 10

s1=Student()
s1.mks+=5
print(s1.mks)
s2=Student()
mks 10 mks 10
print(s2.mks)
print(Student.mks) Instance Namespace of S1 Instance Namespace of S2

Class Namespace
mks 10

mks 15 mks 10

Instance Namespace of S1 Instance Namespace of S2 14


class Student:
mks=10

15
s1=Student()
15
s1.mks+=5 20
print(s1.mks) 20
Student.mks=20
print(s1.mks)
s2=Student()
print(s2.mks)
print(Student.mks)

15
class Sample:
x = 10
@classmethod x in S1= 10
def modify(cls): x in S2= 10
cls.x+=1 x in S1= 11
x in s2= 11
s1 = Sample() x in S1 after modification= 16
s2 = Sample() x in S2= 11
print('x in S1= ',s1.x) x in S2= 20
print('x in S2= ',s2.x) x in s2 after modification= 25
s1.modify() x Value= 20
print('x in S1= ',s1.x) x Value= 21
print('x in s2= ',s2.x) x value= 16
s1.x+=5
print('x in S1 after modification= ',s1.x)
print('x in S2= ',s2.x)
Sample.x=20
print('x in S2= ',s2.x)
s2.x=25
print('x in s2 after modification= ',s2.x)
print('x Value= ',Sample.x)
s2.modify()
print('x Value= ',Sample.x)
print('x value= ',s1.x) 16
Types of Methods

• Instance Methods
a. Accessor methods
b. Mutator methods
• Class Methods
• Static Methods

17
Instance Methods
 Methods acting on Instance Variables.

Example:
class Rectangle():
def __init__(self, l, w): # self refers to the memory address of the instance
self.length = l # instance variable length
self.width = w # instance variable width

def rectangle_area(self): # instance Method


return self.length*self.width

newRectangle = Rectangle(12, 10)


print(newRectangle.rectangle_area())

18
Accessor and Mutator methods
Example:
class Rectangle():
# mutator method
def setsides(self, l, w): # Not just read the variables, but also modify them
self.length = l
self.width = w

# accessor method
def getsides(self): # simply access or read data of variables
return self.length
return self.width

def rectangle_area(self): # instance Method


return self.length*self.width

newRectangle = Rectangle()
newRectangle.setsides(12, 10)
print(newRectangle.getsides())
19
Class Methods
class Sample:
x = 10

@classmethod # built-in decorator statement


def modify(cls):
cls.x+=1

s1 = Sample()
s2 = Sample()
print('x in S1= ',s1.x)
print('x in S2= ',s2.x)
s1.modify()
print('x in S1= ',s1.x)
print('x in S2= ',s2.x)
print('x Value= ',Sample.x)

20
Static Methods
• Static methods in Python are extremely similar to python class level methods,
the difference being that a static method is bound to a class rather than the
objects for that class.
• This means that a static method can be called without an object for that class.
• This also means that static methods cannot modify the state of an object as
they are not bound to it.
• Generally used as a utility method
Example
class Calculator:
# create addNumbers static method
@staticmethod
def multiplyNums(x, y):
return x * y

print('Product:', Calculator.multiplyNums(15, 110))

21
Write a program that counts the number of instances created
for a class
#understanding static methods
#Counting the number of objects created for a class
class MyClass:
n = 0 #this is a class variable or static variable

def __init__(self): #constructor


MyClass.n = MyClass.n+1

#static method to display the no. of instances


@staticmethod
def noObjects():
print('Number of instances created: ',MyClass.n)

ob1 = MyClass()
ob2 = MyClass()
MyClass.noObjects()

22
Write a program to accept and display the following details of an
Employee:
Id, Name, Gender, Age, Designation, Date of Joining, Basic Salary

23
Passing Members of One class to Another Class
class Emp:
def __init__(self,id,name,salary): Output
self.id = id Id= 101
self.name = name Name= Hari
self.salary = salary Salary= 51000
Id= 103
def display(self): Name= John
print('Id= ',self.id) Salary= 21000
print('Name= ',self.name)
print('Salary= ',self.salary)

class UpdateSal:
@staticmethod
def incsalary(e):
e.salary+=1000
e.display()

e1=Emp(101,'Hari', 50000)
UpdateSal.incsalary(e1)
e2=Emp(103,'John',20000)
24
UpdateSal.incsalary(e2)
Inner Classes
#Inner Classes
class Person: Output
def __init__(self): Name= John
self.name ='John'
Date of Birth = 10/12/2000
self.db = self.DoB() #this is DoB object
2000
def display(self):
print('Name= ',self.name)

class DoB:
def __init__(self):
self.dd =10
self.mm =12
self.yy =2000
def display(self):
print('Date of Birth = {}/{}/{}'.format(self.dd,self.mm,self.yy))

p= Person() # create outer class object


p.display() # call outer class method
x=p.db # create inner class object
x.display() # call inner class method
print(x.yy) # refer to inner class instance variable
25
Inner Classes
#Inner Classes
class Person: Output
def __init__(self):
self.name ='John' Name= John
def display(self): Date of Birth = 10/12/2000
print('Name= ',self.name) 2000

class DoB:
def __init__(self):
self.dd =10
self.mm =12
self.yy =2000
def display(self):
print('Date of Birth = {}/{}/{}'.format(self.dd,self.mm,self.yy))

p= Person() # create outer class object


p.display() # call outer class method

x=Person().DoB() # create inner class object


x.display() # call inner class method
print(x.yy) # refer to inner class instance variable 26
class Student:
def __init__(self,name,rollno):
self.name = name
self.rollno = rollno Ram 21
self.lap = None #lap is the obj of a Dell i3
inner class

def show(self):
print(self.name,self.rollno)

class Laptop: #inner class


def __init__(self,brand,cpu):
self.brand = brand
self.cpu = cpu
def show(self):
print(self.brand,self.cpu)

s1 = Student('Ram',21)
s1.show()
lap1 =s1.Laptop('Dell','i3')
lap1.show() 27
Reusable modules
class Teacher:
def setid(self, id):
self.id = id
def getid(self): teacher.py
return self.id

def setname(self, name):


self.name = name
def getname(self):
return self.name

def setaddress(self, address):


self.address = address
def getaddress(self):
return self.address

def setsalary(self, salary):


self.salary = salary
def getsalary(self):
return self.salary 28
Reusing the code of teacher.py

from teacher import Teacher


t = Teacher()
t.setid(10)
t.setname('John')
t.setaddress('18, I street, Bangalore')
t.setsalary(50000)

print('Id= ', t.getid())


print('Name= ', t.getname())
print('Address= ',t.getaddress())
print('Salary= ',t.getsalary())

Output
Id= 10
Name= John
Address= 18, I street, Bangalore
Salary= 50000

29
Reusable modules
class Student: student.py from student import Student
def setid(self, id): s = Student()
self.id = id s.setid(15)
def getid(self): s.setname('James')
return self.id s.setaddress('10, III street, Bangalore')
s.setmarks(85)
def setname(self, name):
self.name = name print('Id= ', s.getid())
def getname(self): print('Name= ', s.getname())
return self.name print('Address= ',s.getaddress())
print('Marks= ',s.getmarks())
def setaddress(self, address):
self.address = address
def getaddress(self):
return self.address

def setmarks(self, marks):


self.marks = marks
def getmarks(self): 30
return self.marks
Creating Student Class by deriving it from Teacher Class
from teacher import Teacher from student import Student
class Student(Teacher): s = Student()
def setmarks(self, marks): s.setid(15)
s.setname('James')
self.marks = marks s.setaddress('10, III street, Bangalore')
def getmarks(self): s.setmarks(85)
return self.marks
print('Id= ', s.getid())
print('Name= ', s.getname())
print('Address= ',s.getaddress())
print('Marks= ',s.getmarks())
class Subclass(Baseclass)

31
Constructors in Inheritance
# Constructor in Inheritance
class Father:
def __init__(self):
self.asset = 1000000
def display_asset(self):
print('Father\'s asset = ', self.asset)

class Son(Father):
pass

s= Son()
s.display_asset()

Output
Father's asset = 1000000

32
Overriding Super Class Constructors and Methods
# Overriding the base class constructor and method in sub class
class Father:
Output
def __init__(self): Son's asset = 2000000
self.asset = 1000000
def display_asset(self):
print('Father\'s asset = ', self.asset)

class Son(Father):
def __init__(self):
self.asset = 2000000
def display_asset(self):
print('Son\'s asset = ', self.asset)

s=Son()
s.display_asset()
33
The super() Method
# Accessing the base class constructor and method in sub class
class Father:
def __init__(self, asset=0): Output
self.asset = asset Total asset of Son = 3000000
def display_asset(self):
print('Father\'s asset = ', self.asset)

class Son(Father):
def __init__(self, asset1=0, asset=0):
super().__init__(asset)
self.asset1 = asset1
def display_asset(self):
print('Total asset of Son = ', self.asset1+self.asset)

s= Son(2000000, 1000000)
s.display_asset()

34
The super() method

• Super() is a built-in method that has the history of super class


methods
• Can be used as
– super().__init__()
– super().__init__(arguments)
– super().method()

35
The super() Method
# Accessing the base class constructor and method in sub class
class Father:
def __init__(self, asset=0): Output
self.asset = asset Total asset of Son = 3000000
def display_asset(self): Father's asset = 1000000
print('Father\'s asset = ', self.asset)

class Son(Father):
def __init__(self, asset1=0, asset=0):
super().__init__(asset)
self.asset1 = asset1
def display_asset(self):
print('Total asset of Son = ', self.asset1+self.asset)
super().display_asset()

s= Son(2000000, 1000000)
s.display_asset()

36
A Python program to access base constructor and methods in the sub
class using super()
class Square: Output
def __init__(self, x): Enter two measurements: 4 5
self.x =x Area of square= 16.0
def area(self): Area of rectangle= 20.0
print('Area of square= ', self.x *self.x)

class Rectangle(Square):
def __init__(self,x,y):
super().__init__(x)
self.y = y
def area(self):
super().area()
print('Area of rectangle= ',self.x * self.y)

a,b = [float(x) for x in input('Enter two measurements: ').split()]


r = Rectangle(a,b)
r.area()
37
Single Inheritance
# Deriving one or more sub classes from a single base class
class Bank(object):
cash = 100000000 Output
@classmethod 100000000
def available_cash(cls): 300000000
print(cls.cash)

class XYZBank(Bank):
pass

class ABCBank(Bank):
cash = 200000000
@classmethod
def available_cash(cls):
print(cls.cash + Bank.cash)

a = XYZBank()
a.available_cash()
b = ABCBank()
38
b.available_cash()
Multiple Inheritance
class subclass(BaseClass1, BaseClass2,….):

39
Multiple Inheritance
# Deriving a sub class from multiple base classes
class Bowler: Output
def print(self): I am a Bowler
I am a Batsman
print('I am a Bowler')

class Batsman:
def display(self):
print('I am a Batsman')

class AllRounder(Bowler,Batsman):
pass

player =AllRounder()
player.print()
player.display()
40
Create a class called Leader. Derive this class from the
base classes Person and Employee.
The attributes of Person class are name and idnumber.
The attributes of Employee class are salary and post.

41
Multiple Inheritance
# first parent class
class Person:
def __init__(self, name, idnumber):
self.name = name
self.idnumber = idnumber
print('Name: ',name, ' Idnumber: ',idnumber)

# second parent class


class Employee(object):
def __init__(self, salary, post):
self.salary = salary
self.post = post
print('Salary: ',salary, ' Post: ',post)

42
# inheritance from both the parent classes
class Leader(Person, Employee):
def __init__(self, name, idnumber, salary, post, votes):
self.votes = votes
Person.__init__(self,name,idnumber)
Employee.__init__(self,salary,post)
print('Votes: ',votes)

ins = Leader('Rahul', 12467, 75000, 'General Manager' ,60)

Output
Name: Rahul Idnumber: 12467
Salary: 75000 Post: General Manager
Votes: 60

43
Problems in Multiple Inheritance
# When super class have constructors
class A(object): Output
def __init__(self): c
self.a = 'a' a
print(self.a)

class B(object):
def __init__(self):
self.b = 'b'
print(self.b)

class C(A, B):


def __init__(self):
self.c = 'c'
print(self.c)
super().__init__()
obj=C()
44
Problems in Multiple Inheritance
# When super class have constructors Output
class A(object): c
pass b

class B(object):
def __init__(self):
self.b = 'b'
print(self.b)

class C(A, B):


def __init__(self):
self.c = 'c'
print(self.c)
super().__init__()
obj=C()

45
Problems in Multiple Inheritance
class A(object):
def __init__(self): Output
self.a ='a'
c
print(self.a)
a
super().__init__()
b
class B(object):
def __init__(self):
self.b ='b'
print(self.b)
super().__init__()

class C(A, B):


def __init__(self):
self.c ='c'
print(self.c)
super().__init__()

obj=C() 46
Method Resolution Order
Method Resolution Order defines the order in which the base classes
are searched when executing a method.

First, the method or attribute is searched within a class and then it


follows the order we specified while inheriting.

Example- class C(A,B):

Object

2 3

47
Method Resolution Order(MRO)
1. Search for the sub class before going for its
base classes.
2. When a class is inherited from several
classes, it searches in the order from left to
right in the base classes.
3. It will not visit any class more than once.

48
Example
class A:
def process(self): Object
print('A process()')

class B(A):
pass

class C(A):
def process(self):
print('C process()')

class D(B,C):
pass C process()

obj = D() (<class '__main__.D'>, <class '__main__.B'>, <class


obj.process() '__main__.C'>, <class '__main__.A'>, <class 'object'>)
print(D.__mro__)
print(D.mro()) [<class '__main__.D'>, <class '__main__.B'>, <class
'__main__.C'>, <class '__main__.A'>, <class 'object'>]
49
class F(object):
pass Object
class E(object):
pass
class D(object): D E F
pass
class C(D,F):
pass B C
class B(D,E):
pass
class A(B,C):
A
pass
print(A.__mro__)
(<class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>,
print() <class '__main__.D'>, <class '__main__.E'>, <class '__main__.F'>,
print(B.mro()) <class 'object'>)

[<class '__main__.B'>, <class '__main__.D'>, <class '__main__.E'>,


<class 'object'>] 50
Polymorphism

 Duck typing philosophy of Python


 Operator overloading
 Method overloading
 Method overriding

51
Duck typing philosophy

1. Python’s type system is ‘strong’ because every variable or object has a


type that we can check with the type() function.
2. Python’s type is ‘dynamic’ since the type of a variable is not explicitly
declared, but it changes with the content being stored.

If it looks like a duck, swims like a duck, and quacks like a duck, then it
probably is a duck.
By analogy, for computing languages, the type of an object is not important so
long as it behaves as expected

52
Duck typing philosophy - Example
# duck typing example
class Duck: Ouput
def talk(self): Quack Quack
print('Quack Quack') Hello

class Human:
def talk(self):
print('Hello')

def call_talk(obj):
obj.talk()

x= Duck()
call_talk(x)
x= Human()
call_talk(x)
53
# duck typing example
class Dog:
def bark(self): def call_talk(obj)
print('Bow') if hasattr(obj, 'talk'):
obj.talk()
class Duck: elif hasattr(obj, 'bark'):
def talk(self): obj.bark()
print('Quak Quak')

class Human:
def talk(self):
print('Hello')

def call_talk(obj)
obj.talk()

x= Duck()
call_talk(x)
x= Human()
call_talk(x)
x=Dog()
call_talk(x) #Attribute Error occurs in this call 54
Operator Overloading
• When an operator can perform different actions, it is said to exhibit
polymorphism.
• If any operator performs additional actions other than what it is
meant for, it is called Operator Overloading

Example
# Overloading the + operator
print(10+100)

s1 = 'News'
s2= 'Paper' 110
print(s1+s2) NewsPaper
[10, 49, 60, 35, -50, 20]
a = [10,49,60]
b = [35,-50,20]
print(a+b)
55
# using + operator on objects
class Bookx:
def __init__(self, pages): a + b ⇒ a. __add__(b)
self.pages = pages

def __add__(self, other):


return self.pages + other.pages

class Booky:
def __init__(self, pages):
self.pages = pages

b1 = Bookx(100)
b2 = Booky(200)
print('Total pages = ', b1 + b2)
56
Magic Methods

Operator Method
+ object.__add__(self, other)
- object.__sub__(self, other)
* object.__mul__(self, other)
// object.__floordiv__(self, other)
/ object.__truediv__(self, other)
% object.__mod__(self, other)
** object.__pow__(self, other[, modulo])
<< object.__lshift__(self, other)
>> object.__rshift__(self, other)
& object.__and__(self, other)
^ object.__xor__(self, other)
| object.__or__(self, other)
57
Magic Methods

Operator Method
+= object.__iadd__(self, other)
-= object.__isub__(self, other)
*= object.__imul__(self, other)
/= object.__idiv__(self, other)
//= object.__ifloordiv__(self, other)
%= object.__imod__(self, other)
**= object.__ipow__(self, other[, modulo])
<<= object.__ilshift__(self, other)
>>= object.__irshift__(self, other)
&= object.__iand__(self, other)
^= object.__ixor__(self, other)
|= object.__ior__(self, other)
58
Magic Methods

Operator Method
- object.__neg__(self)
+ object.__pos__(self)
abs() object.__abs__(self)
~ object.__invert__(self)
complex() object.__complex__(self)
int() object.__int__(self)
long() object.__long__(self)
float() object.__float__(self)
oct() object.__oct__(self)
hex() object.__hex__(self

59
Magic Methods

Operator Method
< object.__lt__(self, other)
<= object.__le__(self, other)
== object.__eq__(self, other)
!= object.__ne__(self, other)
>= object.__ge__(self, other)
> object.__gt__(self, other)

60
# using > operator on objects
class Bookx:
def __init__(self, pages):
self.pages = pages

def __gt__(self, other):


return self.pages > other.pages

class Booky:
def __init__(self, pages):
self.pages = pages

b1 = Bookx(100)
b2 = Booky(200)
if (b1>b2):
print(' Bookx has more pages')
else:
print(' Booky has more pages')
61
import math
class Circle:
def __init__(self,radius):
self.radius = radius
def __add__(self,another_circle):
return Circle(self.radius + another_circle.radius)
def getRadius(self):
return self.radius

c1 = Circle(4)
print(c1.getRadius())

c2 = Circle(5)
print(c2.getRadius())

c3 = c1 + c2
# This became possible because we have overloaded + operator by
adding a method named __add__
print(c3.getRadius()) 62
Method Overloading
 A method is written such that it can perform more than one task, is called
method overloading.

 Writing more than one method with the same name is not possible in
Python.

 We achieve method overloading by writing same method with several


parameters.

 The method performs the operation depending on the number of


arguments passed in the method call.

63
# method overloading
class Myclass:
def sum(self, a = None, b=None, c=None):
if a!=None and b!=None and c!= None:
print('Sum of three = ',a+b+c)
elif a!=None and b!=None:
print('Sum of two = ',a+b)
else:
print('Please enter two or three arguments')

#call sum() using object


m = Myclass()
m.sum(10,10.5)
m.sum(10,50,10)
m.sum(10)
64
Overriding
class Rectangle():
def __init__(self,length,breadth):
self.length = length
self.breadth = breadth
def getArea(self):
print (self.length*self.breadth," is area of rectangle")

class Square(Rectangle):
def __init__(self,side):
self.side = side
Rectangle.__init__(self,side,side)
def getArea(self):
print (self.side*self.side," is area of square")
s = Square(4)
r = Rectangle(2,4)
s.getArea()
r.getArea()

65
Abstract classes and Interfaces
 Abstract method is a method whose action is redefined in the sub classes
as per the requirement of the objects.
 Generally abstract methods are written without body since their body will
be defined in the sub classes.
 But, it is possible to write an abstract method with body also.
 The decorator @abstractmethod is used to mark a method as abstract.

66
#abstract class example class Sub2(Myclass):
#Abstract Base Class def calculate(self,x):
from abc import ABC, abstractmethod print('Square root ',math.sqrt(x))
# or from abc import *
import math class Sub3(Myclass):
def calculate(self,x):
class Myclass(ABC): print('Cube value ',x**3)
@abstractmethod
def calculate(self,x): obj1= Sub1()
pass obj1.calculate(5)
obj2= Sub2()
#This is a subclass of Myclass obj2.calculate(36)
class Sub1(Myclass): obj3= Sub3()
def calculate(self,x): obj3.calculate(3)
print('Square value ',x*x)

67
Interfaces
An interface is an abstract class but it contains only abstract methods.
None of the methods in the interface will have body.
Only method headers will be written in the interface.
Interface can be defined as a specification of method headers

68
Program to develop an interface that connects to any database
# Abstract class works like an interface #This is another subclass
from abc import * class Sybase(Myclass):
class Myclass(ABC): def connect(self):
@abstractmethod print('Connecting to Sybase database')
def connect(self): def disconnect(self):
pass print('Disconnected from Sybase')
@abstractmethod
def disconnect(self): class Database:
pass str = input('Enter database name: ')
print(globals()[str])
#This is a subclass
class Oracle(Myclass): classname = globals()[str]
def connect(self):
print('Connecting to Oracle database') x=classname()
def disconnect(self): x.connect()
print('Disconnected from Oracle') x.disconnect()

OUTPUT Enter database name: Sybase


<class '__main__.Sybase'>
Connecting to Sybase database
Disconnected from Sybase 69
Comparison between Abstract Class and Interface

Abstract Class Interface


Example of Polymorphism Example of Polymorphism

Written when there are some Written when all the features are
common features shared by all implemented differently by
the objects different objects
When an interface is written any
third party vendor can provide
sub classes.

70
Write a program to find the area of
i) Square
ii) Regular Pentagon
iii) Regular hexagon
(Note: Use Abstract class with an abstract method by name area)

71

You might also like