Unit V - Object Oriented Programming in Python
Unit V - Object Oriented Programming in Python
OBJECT ORIENTED
PROGRAMMING IN PYTHON
INTRODUCTION:
🞆Python follows object oriented programming paradigm. It deals
with declaring python classes and objects which lays the
foundation of OOP’s concepts.
🞆It uses the OOP concepts that makes python more powerful to
help design a program that represents real world entities.
🞆Python supports OOP concepts such as Inheritance, Method
Overriding, Data abstraction and Data hiding.
DIFFERENT OOP FEATURES SUPPORTED BY PYTHON:
🞆 Class: A class is a collection of objects or you can say it is a
blueprint of objects defining the common attributes and
behavior. Classes are defined by the user. The class provides
the basic structure for an object. It consists of data members and
method members that are used by the instances(object) of the
class.
🞆 Object: Objects are an instance of a class. It is an entity that
has state and behavior. A unique instance of a data structure
that is defined by its class. An object comprises both data
members and methods. Class itself does nothing but real
functionality is achieved through their objects.
🞆 Data Member: A variable defined in either a class or an object;
it holds the data associated with the class or object.
🞆 Instance variable: A variable that is defined in a method, its
scope is only within the object that defines it.
DIFFERENT OOP FEATURES SUPPORTED BY
PYTHON:
🞆Class variable: A variable that is defined in the class and can be
used by all the instance of that class.
🞆Instance: An object is an instance of a class.
🞆Method: They are functions that are defined in the definition of
class and are used by various instances of the class.
🞆Function Overloading: A function defined more than one time
with different behavior. (different arguments)
🞆Encapsulation: It is the process of binding together the methods
and data variables as a single entity i.e. class. It hides the data
within the class and makes it available only through the methods.
DIFFERENT OOP FEATURES SUPPORTED
BY PYTHON:
🞆Inheritance: The transfer of characteristics of a class to other
classes that are derived from it.
🞆Polymorphism: It allows one interface to be used for a set of
actions. It means same function name(but different signatures)
being used for different types.
🞆Data abstraction: It is the process of hiding the implementation
details and showing only functionality to the user.
CREATING CLASSES:
🞆A Class is like an object constructor, or a "blueprint" for
creating objects
🞆Syntax:
class ClassName:
‘ Optional class documentation string
#list of python class variables
# Python class constructor
#Python class method definitions
🞆In a class we can define variables, functions etc. While writing
function in class we have to pass atleast one argument that is
called self parameter.
🞆The self parameter is a reference to the class itself and is used to
access variables that belongs to the class.
🞆Example: Creating class in .py file
class student:
def display(self):
print("Hello Python")
🞆In python programming self is a default variable that contains the
memory address of the instance of the current class.
🞆So we can use self to refer to all the instance variable and
instance methods.
OBJECTS AND CREATING OBJECTS:
🞆An object is an instance of a class that has some attributes and
behavior.
🞆Objects can be used to access the attributes of the class.
🞆Syntax:
object_name=class_name()
🞆Example:
class student:
def display(self): # defining method in class
print("Hello Python")
s1=student() #creating object of class
s1.display() #calling method of class using object
🞆Output: Hello Python
DATA HIDING:
🞆Data hiding is a software development technique specifically
used in object oriented programming to hide internal object
details(data members).
🞆Data hiding is also known as information hiding. An object
attributes may or may not be visible outside the class definition.
🞆We need to name attributes with a double underscore
(_ _) prefix and those attributes the are not directly visible to
outsiders. Any variable prefix with double underscore is called
private variable which is accessible only with class where it is
declared.
🞆Example: For data hiding
class counter:
__secretcount=0 # private variable
def count(self): # public method
self.__secretcount+=1
print("count= ",self.__secretcount)
c1=counter()
c1.count() # invoke method
c1.count()
print("Total count= ",c1.__secretcount)
🞆Output:
count= 1
count= 2
AttributeError: 'counter' object has no attribute '__secretcount'
DATA ENCAPSULATION AND DATA
ABSTRACTION:
🞆We can restrict access of methods and variables in a class with
the help of encapsulation. It will prevent the data being modified
by accident.
🞆Data abstraction refers to providing only essential information
about the data to the outside world, hiding the background details
of implementation.
🞆Encapsulation is a process to bind data and functions together
into a single unit i.e. class while abstraction is a process in which
the data inside the class is the hidden from outside world.
🞆In short hiding internal details and showing functionality is
known as abstraction.
ACCESS MODIFIERS FOR VARIABLES AND METHODS ARE:
🞆Public methods / variables-:
Accessible from anywhere inside the class, in the sub
class, in same script file as well as outside the script file.
🞆Private methods / variables:
Accessible only in their own class. Starts with two
underscores.
🞆 Example: For access modifiers with data abstraction
class student:
__a=10 #private variable
b=20 #public variable
def __private_method(self): #private method
print("Private method is called")
def public_method(self): #public method
print("public method is called")
print("a= ",self.__a) #can be accessible in same class
s1=student()
# print("a= ",s1.__a) #generate error
print("b=",s1.b)
# s1.__private_method() #generateerror
s1.public_method()
🞆 Output:
b= 20
public method is called
a= 10
CREATING CONSTRUCTOR:
🞆Constructors are generally used for instantiating an object.
🞆The task of constructors is to initialize(assign values) to the data
members of the class when an object of class is created.
🞆In Python the __init__() method is called the constructor and is
always called when an object is created.
🞆Syntax of constructor declaration :
def __init__(self):
# body of the constructor
🞆 Example: For creating constructor use_ _init_ _ method called as
constructor.
class student:
def __init__(self,rollno,name,age):
self.rollno=rollno
self.name=name
self.age=age
print("student object is created") p1=student(11,"Ajay",20)
print("Roll No of student= ",p1.rollno)
print("Name of student= ",p1.name)
print("Age of student= ",p1.age)
🞆 Output:
student object is created
Roll No of student= 11
Name of student= Ajay
Age of student= 20
🞆 Create a circle class and initialize it with radius. Make two methods
getarea and getcircumference inside this class :
class circle:
def __init__(self,radius):
self.radius=radius
def getarea(self):
return 3.14*self.radius*self.radius
def getcircumference(self):
return 2*3.14*self.radius
c=circle(5)
print("Area=",c.getarea())
print("Circumference=",c.getcircumference())
🞆 Output:
Area= 78.5
Circumference= 31.400000000000002
TYPES OF CONSTRUCTOR:
There are two types of constructor-
🞆Default constructor- The default constructor is simple
constructor which does not accept any arguments. Its definition
has only one argument which is a reference to the instance being
constructed.
class student:
def __init__(self):
print("This is non parameterized constructor")
def show(self,name):
print("Hello",name)
s1=student()
s1.show("World")
🞆Output: This is non parameterized constructor
Hello World
🞆Example: For parameterized constructor
class student:
def __init__(self,name):
print("This is parameterized constructor")
self.name=name
def show(self):
print("Hello",self.name)
s1=student("World")
s1.show()
🞆Output:
This is parameterized constructor
Hello World
DESTRUCTOR:
🞆 A class can define a special method called destructor with the help of _ _del_
_().
🞆 It is invoked automatically when the instance (object) is about to be destroyed.
🞆 It is mostly used to clean up memory resources not used by an
instance(object).
🞆 Example: For Destructor
class student:
def __init__(self):
print("This is non parameterized constructor")
def __del__(self):
print("Destructor called")
s1=student()
s2=student()
del s1
🞆 Output: This is non parameterized constructor
This is non parameterized constructor
Destructor called
METHOD OVERLOADING:
🞆Method overloading is the ability to define the method with the
same name but with a different number of arguments and data
types.
🞆With this ability one method can perform different tasks,
depending on the number of arguments or the types of the
arguments given.
🞆Method overloading is a concept in which a method in a class
performs operations according to the parameters passed to it.
🞆As in other language we can write a program having two
methods with same name but with different number of arguments
or order of arguments but in python if we will try to do the same
we get the following issue with method overloading in python.
🞆Example- # To calculate area of rectangle
def area(length,breadth):
calc=length*breadth
print(calc)
# To calculate area of square
def area(size):
calc=size*size
print(calc)
area(3)
area(4,5)
🞆Output: 9
Traceback (most recent call last): File "D:\python programs\
trial.py", line 10, in area(4,5)
TypeError: area() takes 1 positional argument but 2 were given
🞆 Python does not support method overloading i.e it is not possible to define
more than one method with the same name in a class in python.
🞆 This is because method arguments in python do not have a type. A method
accepting one argument can be called with an integer value, a string or a
double as shown in example.
🞆 Example:
class demo:
def print_r(self,a,b):
print(a)
print(b)
obj=demo()
obj.print_r(10,'S')
obj.print_r('S',10)
🞆 Output:
10
S
S
10
🞆In the above example same method works for two
different data types.
🞆It is clear that method overloading is not supported in
python but that does not mean that we cannot call a
method with different number of arguments.
🞆There are couple of alternatives available in python that
make it possible to call the same method but with
different number of arguments.
USING DEFAULT ARGUMENTS:
🞆 It is possible to provide default values to method arguments while defining a method. If
method arguments are supplied default values, then it is not mandatory to supply those
arguments while calling method as shown in example.
🞆 Example 1: Method overloading with default arguments
class demo:
def arguments(self,a=None,b=None,c=None):
if(a!=None and b!=None and c!=None):
print("3 arguments")
elif (a!=None and b!=None):
print("2 arguments")
elif (a!=None):
print("1 argument")
else:
print("0 arguments")
obj=demo()
obj.arguments("Amol","Kedar","Sanjay")
obj.arguments("Amit","Rahul")
obj.arguments("Sidharth")
obj.arguments()
INHERITANCE:
🞆The mechanism of designing and constructing classes from
other classes is called inheritance.
🞆Inheritance is the capability of one class to derive or inherit the
properties from some another class.
🞆The new class is called derived class or child class and the class
from which this derived class has been inherited is the base class
or parent class.
🞆The benefits of inheritance are:
1. It represents real-world relationships well.
2. It provides reusability of a code.
3. It is transitive in nature, which means that if class B inherits
from another class A, then all the subclasses of B would
automatically inherit from class A.
TYPES OF INHERITANCES:
🞆Single Inheritance.
🞆Multiple Inheritance.
🞆Multilevel Inheritance.
🞆Hierarchical Inheritance.
🞆Hybrid Inheritance.
SINGLE INHERITANCE
🞆When child class is derived from only one parent class.
This is called single inheritance.
🞆Syntax:
Class A:
# Properties of class A
Class B(A):
# Class B inheriting property of class A
# more properties of class B
EXAMPLE OF SINGLE INHERITANCE:
# Base class
class Parent:
def func1(self):
print("This function is in parent class.")
# Derived class
class Child(Parent):
def func2(self):
print("This function is in child class.")
object = Child()
object.func1()
object.func2()
🞆 Output:
Class A:
# variable of class A
# functions of class A
Class B:
# variable of class B
# functions of class B
Class C(A,B):
# Class C inheriting property of both class A and B # more properties
of class C
EXAMPLE 1 OF MULTIPLE INHERITANCE:
# Base class1 # Derived class
class Mother: class Son(Mother, Father):
def parents(self):
mothername = ""
print("Father :", self.fathername)
def mother(self):
print("Mother :",
print(self.mothername) self.mothername)
d2.derived2_method()
class Student1(School):
def func2(self):
print("This function is in student 1. ")
class Student2(School):
def func3(self):
print("This function is in student 2.")
# Driver's code
object = Student3()
object.func1()
object.func2()
Output:
This function is in school.
This function is in student 1.
METHOD OVERRIDING:
🞆Method overriding is an ability of a class to change the
implementation of a method provided by one of its base class.
🞆Method overriding is thus a strict part of inheritance
mechanism.
🞆To override a method in base class, we must define a new
method with same name and same parameters in the derived
class.
🞆Overriding is a very important part of OOP since it is feature
that makes inheritance exploit its full power. Through method
overriding a class may “copy” another class, avoiding
duplicated code and at the same time enhance or customize
part of it.
🞆Example: For method overriding
class A:
def display(self):
print("This is base class")
class B(A):
def display(self):
print("This is derived class")
obj=B() # instance of child
obj.display() # child calls overridden method
🞆Output:
This is derived class
USING SUPER() METHOD:
🞆The super() method gives you access to methods in a super
class from the subclass that inherits from it.
🞆The super() method returns a temporary object of the
superclass that then allows you to call that superclass’s method.
🞆Example: For method overriding with super()
class A:
def display(self):
print("This is base class")
class B(A):
def display(self):
super().display()
print("This is derived class")
obj=B() # instance of child
obj.display() # child calls overridden method
🞆Output:
This is base class
This is derived class
What is Composition (Has-A Relation)
● It is one of the fundamental concepts of Object-Oriented Programming. In this
concept, we will describe a class that references to one or more objects of
other classes as an Instance variable.
● Here, by using the class name or by creating the object we can access the
members of one class inside another class.
● It enables creating complex types by combining objects of different classes. It
means that a class Composite can contain an object of another class
Component.
● This type of relationship is known as Has-A Relation
SYNTAX:
class A :
# variables of class A
# methods of class A
...
...
class B :
# by using "obj" we can access members of class A.
obj = A()
# variables of class B
# methods of class B
...
...
class Component:
# composite class constructor
def __init__(self):
print('Component class object created...')
# composite class instance method
def m1(self):
print('Component class m1() method executed...')
class Composite:
# composite class constructor
def __init__(self):
# creating object of component class
self.obj1 = Component()
print('Composite class object also created...')
# composite class instance method
def m2(self):
print('Composite class m2() method executed...')
# calling m1() method of component class
self.obj1.m1()
# creating object of composite class
obj2 = Composite()
# calling m2() method of composite class
OUTPUT:
🞆 Component class object created...
🞆 Composite class object also created...
🞆 Composite class m2() method executed...
🞆 Component class m1() method executed...
🞆 In the above example, we created two classes Composite and Component
to show the Has-A Relation among them.
🞆 In the Component class, we have one constructor and an instance method
m1().
🞆 Similarly, in Composite class, we have one constructor in which we created
an object of Component Class. Whenever we create an object of Composite
Class, the object of the Component class is automatically created.
🞆 Now in m2() method of Composite class we are calling m1() method of
Component Class using instance variable obj1 in which reference of
Component Class is stored.
🞆 Now, whenever we call m2() method of Composite Class, automatically m1()
method of Component Class will be called.
CUSTOMIZATION VIA INHERITANCE
SPECIALIZING INHERITED METHODS:
🞆The tree-searching model of inheritance turns out to be a great
way to specialize systems. Because inheritance finds names in
subclasses before it checks superclasses, subclasses can replace
default behavior by redefining the superclass's attributes.
🞆In fact, you can build entire systems as hierarchies of classes,
which are extended by adding new external subclasses rather
than changing existing logic in place.
🞆The idea of redefining inherited names leads to a variety of
specialization techniques.
🞆For instance, subclasses may replace inherited attributes
completely, provide attributes that a superclass expects to find,
and extend superclass methods by calling back to the superclass
from an overridden method
🞆 Example- For specialized inherited methods
class A:
"parent class" #parent class
def display(self):
print("This is base class")
class B(A):
"Child class“ #derived class
def display(self):
A.display(self)
print("This is derived class")
obj=B() #instance of child
obj.display() #child calls overridden method
🞆 Output:
This is base class
This is derived class
🞆In the above example derived class.display() just extends base
class.display() behavior rather than replacing it completely.
🞆Extension is the only way to interface with a superclass.