Unit 3
Unit 3
COURSE MATERIAL
For
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,gende
acity r,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.
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.
Example-1 (Constructor without arguments):
def__init__(self):
self.a=10
self.b=20
Example-2 (Constructor with arguments):
def __init__(self,x,y):
self.a=x
self.b=y
def __init__(self):
print(“car object created”)
self.name=’BMW’
self.price=100000
def display(self):
print(“Name=”,self.name)
print(“Price=”,self.price)
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:
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 object or reference variable.
➔ To modify the value of data attribute inside a method syntax is
self.attribute=value
➔ To modify the value of data attribute outside a method syntax is
referenceVariable.attribute=value
or
object_name.attribute=value
➔ We cannot modify the data attribute using a class name
➔ 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.
#child methods
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.
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.
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
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
existing method 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