Unit 312
Unit 312
COURSE MATERIAL
For
Notes prepared by
P. Phani Prasad
Assistant Professor,
Department of CSE,
MVSREC
UNIT-III
TOPICS COVERED
1. Principles of Object Oriented Programming
2. Classes and Objects
3. Creating classes and objects
4. Constructor method
5. Creating multiple objects
6. Class attributes and Data attributes
7. Encapsulation
8. Inheritance
a. Definition and usage
b. Types of inheritance
9. Polymorphism
a. Operator overloading
b. Method overloading
c. Method overriding
10. Data hiding
a. Public and private members
i. Public and private variables
ii. Public and private methods
Attributes: Attributes:
name,price,owner,mileage,color,seatcap name,rollno,marks,branch,college,gend
acity er,year,semester
Methods: Methods:
driveCar(), sellCar(), buyCar(), getStudentDetails(), addStudents(),
registerCar() removeStudents()
What is an object?
An object is an instance of a class or implementation of a class.
As a class cannot execute by itself, it requires an object to interpret the logical design of
the generated class.
→ For a generated class, there could be multiple objects that can be created.
→ Each object has its own memory that could interpret the class.
→ A user can interact with the class through its corresponding object. All the attributes
and methods of a class can be accessed by using the object of that class.
→ Consider the design of a house. To construct a house a blueprint is required. Using that
blueprint we can build multiple houses.
→ Here the blueprint will be a class and each outcome of the house is an object of that
blueprint.Below diagram shows the relation between class and object.
def sell(self):
print(“selling the car”)
def getDetails(self):
print(“details of the car”)
Syntax to create an object:
variable=classname()
Example for creating an object for class ‘car’:
obj=car()
Here car() is an object and obj is a reference variable of type car that refer to the address
of car object
→ Using ‘obj’ we can access all attributes and methods of class ‘car’. To access an
attribute or method dot operator is used as per below syntax.
Accessing an attribute of class:
referenceVariable.attributeName
Example:
print(obj.name) #accessing car name and printing
obj.mileage=’25.34kmph’ #updating car mileage
Accessing/Calling a method of a class:
referenceVariable.methodName()
Example:
obj.driveCar() #calling the method driveCar()
obj.sellCar() #calling the method sellCar()
Sample Program:
Write a program to create a class car with some attributes and methods and implement it.
Solution:
Output:
4. Constructor method
What is a constructor?
A constructor is a special method defined inside a class used to initialize the
attributes of the class for an entity.
→ In python, A method __init__() is used to define the constructor for a class
→ To create a constructor we use the following syntax
Syntax:
def __init__(self [,argument(s)]):
#statements
Note: Square brackets [] in the above syntax indicate that they are optional.
class car:
def __init__(self):
print(“car object created”)
self.name=’BMW’
self.price=100000
def display(self):
print(“Name=”,self.name)
print(“Price=”,self.price)
Consider the below program which prints the address of an object using “self” and
reference variable.
Output:
Notice that both outputs are the same. So we conclude that self refers to the current object
within a class and a reference variable is used to refer to an object outside the class.
5. Creating multiple objects
In a python program, there could be many classes. Each class may contain many objects.
Once a class is defined with a set of attributes and methods, then we can create many
objects.
We can create many objects by either separate reference variables or store and refer them
using a list variable.
Example-1
Example-2 (Creating objects and referencing through a list variable for above
student class)
These two memory addresses can be viewed separately by using id() function and self
parameter. id() function will return stack address and self will return object’s heap
address.
Observe below code:
Output:
classname.attribute=value
➔ We cannot modify the class attribute using a reference variable or
self variable.
Syntax to create class attribute:
class classname:
#class attributes
examples output
b) Data attributes
➔ Attributes which are defined and initialized within constructor or methods
of a class are called data attributes.
➔ Also called instance variables or object variables
➔ These variables should be created and accessed by using “self” parameter.
➔ For multiple objects, multiple data attributes will be created separately.
Assume a class has 5 data attributes and you have created 3 objects for this
class. Then the 5 data attributes will be created 3 times uniquely for each
object.
➔ Scope and lifetime of data attribute is valid between the creation and
deletion of an object
➔ Can be accessed within methods of a class using self parameter
➔ Can be accessed outside a class using a reference variable.
➔ To modify the value of data attribute inside a method syntax is
self.attribute=value
➔ To modify the value of data attribute inside a method syntax is
referenceVariable.attribute=value
➔ We cannot modify the data attribute using a class variable
➔ Data attributes once created can be accessed by all methods of a class
using the “self” parameter.
Syntax to create data attribute:
class classname:
def __init__(self):
#data attributes
def method(self):
#data attributes
Example Output
In this example name,price are data attributes of the class car. Two objects are created. So
name,price are created twice for each object.
7. Data Encapsulation
Wrapping or binding of the attributes and methods of an entity together as a single unit of
block is called Data encapsulation.
● Main aim of encapsulation is to avoid exposure of sensitive data to the outside
class and restrict the users outside of class from modifying it.
● For an application, data for attributes is taken and retrieved methods of class.
Methods are the mediators between the user and sensitive data attributes.
● Example of data encapsulation is creating a class with a set of attributes and
methods. Attributes and methods are binded as a single unit of block called class.
● Data can be restricted by securing it as private variable.
● Example:
class employee:
def __init__(self):
self.name=’ram’
self.salary=50000
self.company=’microsoft’
def display(self):
print(self.name,self.salary,self.company)
8. Inheritance
a. Definition and usage
➔ Inheritance is the ability of acquiring the members from one class to
another class.
➔ Class from which members are borrowed or acquired is called super class
or parent class or base class or generalized class
➔ Class into which members are received or acquired is called sub class or
child class or derived class or specialized class
➔ Main use of inheritance is “Reusability of existing classes by many classes
many times” instead of rewriting the code from scratch by the inheriting
users.
➔ Represent an “is-a” relationship between parent and child classes. For
example, a student class could inherit a few members from another class
person. So here Student is-a person, shows an “is-a” relationship between
person and student classes.
Points to Remember:
➔ Always we create objects for child classes to access the entire code.
➔ Child class can access both parents and the child's members but the parent
class cannot.
➔ Here inheriting members means both attributes and methods of parent
class.
Example Output
b. Types of inheritance
We can inherit the members from one class to another class using the following
ways of inheritance.
i) Single-level inheritance : Inheriting the members from one parent class to
another one child class. Below figure depicts it. A is the parent class and B is the
child class.Object is created for child class.
Syntax:
class A:
#A’s attributes
# A’s methods
class B(A):
#B’s attributes
# B’s methods
Example output
ii) multilevel inheritance: Inheriting the members from one parent class to first
child class and first child class to second child class and so on.. Below figure
depicts it. A is the parent class and B is the first child class, C is the second child
class and Leaf is the last child class. Object is created for leaf class.
Syntax:
class A:
#A’s attributes, methods
class B(A):
#B’s attributes, methods
…
…
class N(N-1):
#N-1’s
attributes,methods
Example Output
10
20
30
iii) multiple inheritance : Inheriting the members from more than one parent
class by a single child class. Object is created for child class.
Syntax:
class A:
#A’s attributes,methods
class B:
#B’s attributes,methods
class C:
#C’s attributes,methods
….
class Z:
#Z’s attributes,methods
class subclass(A,B,C,...Z):
#subclass attributes,methods
Example Output
10
20
30
iv) hierarchical inheritance: Inheriting the members from one parent class by
many child classes. Objects will be created for all child classes.
Syntax:
class A:
#A’s attributes,methods
class B(A):
#B’s attributes,methods
class C(A):
#C’s attributes,methods
….
class Z(A):
#Z’s attributes,methods
Example Output
10
20
10
30
v) Diamond inheritance: Inheriting the members from two child classes which
are already inherited from a single parent class.
An ambiguity may arise between two child classes accessing a common member
from a parent class.
A precise decision will be applied by the python implicitly using a mechanism
called MRO (Method Resolution Order) to inherit the exact members from a
class.
What is MRO?
MRO (Method Resolution Order) is a mechanism of identifying the exact parent
class to be inherited by a child class.
It uses Depth-First Search technique from left-to-right order of inheritance applied
to the child class.
Syntax:
class A:
#A’s attributes,methods
class B(A):
#B’s attributes,methods
class C(A):
#C’s attributes,methods
class D(B,C):
#D’s attributes,methods
Example Output
10
20
30
40
Syntax:
class A:
#A’s members
class B(A):
#B’s members
class C(B):
#C’s members
class D(B):
#D’s members
class E(C):
#E’s members
class F(D):
#F’s members
class G(D):
#G’s members
Example Output
class A: 10
a=10 20
class B(A): 30
b=20 50
class C(B): 10
c=30 20
class D(B): 40
d=40 60
class E(C): 10
e=50 20
def show(self): 40
print(self.a) 70
print(self.b)
print(self.c)
print(self.e)
class F(D):
f=60
def show(self):
print(self.a)
print(self.b)
print(self.d)
print(self.f)
class G(D):
g=70
def show(self):
print(self.a)
print(self.b)
print(self.d)
print(self.g)
obj1=E()
obj2=F()
obj3=G()
obj1.show()
obj2.show()
obj3.show()
9. Polymorphism
Definition: The ability to perform multiple tasks by an operator or method in different
contexts of the program.
The word polymorphism derived from two words poly (which means many) and
morphism (means change to different forms).
There are some operators which behave differently at different situations of the program.
For example, operator ‘+’ can do two things: It performs addition between two numerics
and also performs concatenation between two strings ,two lists or sets etc.
As a user, we can provide a new operation for an operator or a method to behave
differently at a specified context.
a. Operator overloading
● If an operator can do more than one task at different contexts in a
program,then the operator is said to be overloaded.
● We can provide many definitions for an operator to behave differently at a
given context.
● Assume if two rectangles are to be added , then ‘+’ operator should be
defined in such a way that it should add lengths of two rectangles and
breadths of two rectangles.The result of operation will be another
rectangle.
● To overload any operator, we need to define the corresponding operator
method inside a class and provide the operator logic.
Python supports special built-in methods to overload the following operators.
Sample Program:
Write a program to read and add two rectangles using operator overloading.
Program Output
Step-1: Program execution begins from r1=rectangle(2,3) statement. This line creates first
rectangle and calls __init__() to initialize length and breadth for r1
Step-2: This line also creates second rectangle and initializes length and breadth for r2
Step-3: r3=r1+r2 . This line implicitly calls __add__(self,other) method to execute.
This statement is equivalent to r3=r1.__add__(r2)
‘self’ will refer to r1 and ‘other’ will refer to r2.
Computes the addition of r1 and r2 length , r1 and r2 breadth and stores resultant length
and breadth in the rectangle variable ‘t’. Now ‘t’ will be returned.
Step-4: Returned ‘t’ will be referred to by r3 which is a computed rectangle .
Step-5: Displaying all rectangles by calling display() method
Method signature:
A method signature specifies the following things to be observed while defining methods.
i) name of the method
ii) No. of parameters of the method
iii) type of parameters of the method
iv) sequence of parameters of the method
Method signature helps to compare and check if two methods are equal or not as per the above
specification.
b. Method overloading
A method is said to be overloaded if any other method is defined exactly with the
same name but with different numbers and types of parameters in a class.
➔ It is an ability to define more than one method with the same name to
perform multiple different operations.
➔ But in python, we cannot define another method with the same name more
than once.
➔ Because python is an interpreted based language, only the last defined
method will be considered and previous methods will be discarded.
➔ So to achieve this method overloading, we define only one method which
needs to be overloaded with a maximum number of formal arguments.
➔ After a method is defined, we can call the same method many times with
different numbers of actual parameters.
➔ Number of actual parameters should be <= maximum number of formal
arguments in method definition.
Example Output
Note: method overloading is not suitable to write always in python. Instead it is recommended to
use keyword arguments or variable length keyword arguments.
c. Method overriding
During inheritance, if a method defined in parent class and a method defined in
child class have exactly the same method signatures then the child class method is
said to be overriding the parent class method.
➔ While using inheritance, we create objects for child class. So by default
the child class method will be invoked when two method signatures are
the same between parent and child class methods.
➔ Parent class method will be invisible to call when a child class object is
created.
➔ To overcome this, we use the “super()” function.
➔ “super()” function : A “super()” function is used to refer to the parent class
and calls explicitly parent class methods.
➔ When the child class method overrides the parent class method, super()
function calls the parent class method explicitly.
Observe the below examples. First is without using super() and other is using with ‘super()’
Example-1 Output
Note: In the above example, parent’s compute not called as it was overridden by child’s
compute.
Example-2 output
Note: In the above example, parent’s compute also called using the super() function along with
child’s compute.
Differences between method overloading and method overriding:
Methods must have same name but with Methods defined in parent and child class
different number of parameters must have same method signatures
Used to add additional behavior to the To modify the behavior of the existing method
existing method
Note: By default, all class attributes of a class are private attributes. They cannot modified
outside the class
Example Output
Observe the below examples of using both public and private methods
Example-1 output
show method
Example-2 output
Example-3 output
show method