Unit -3 OOPs Python Stds
Unit -3 OOPs Python Stds
Note : Python class names are written in Captalizad words notation by convention
Object : An object is an instance of a class . objects share the same functions with other objects of the
same class but each object (each instance) has its own copy of the data structure. Objects are instances
of classes and are used to interact amongst each other to create applications.
A class is a logical construct and an object is a physical construct. It means that when class is
defined no memory is allocated but when object is created , memory is allocated.
The object's attributes are initialised in the constructor, which is a special procedure with the
name __init__.
So an object consists of:
State: It is represented by the attributes of an object. .
Behavior: It is represented by the methods of an object.
Identity: It gives a unique name to an object.
Creating an Object : Creating a new object from a class is called instantiating a class. You can
create a new object by typing the name of the class, followed by opening and closing parentheses:
Syntax:
Std = Students ( ) # Creating instance of the Students class and assign it to the variable Std
Std.showdata( ) # Accessing the member function showdata
Data Encapsulation
Data encapsulation is one of the key features of object-oriented programming.. It is the
mechanism that binds code and data together in a single unit ( called Class) and keeps them safe and
away from outside inference and misuse. Encapsulation is placing the data and the functions that work
on that data in the same place In short, it isolates a data from outside world. Encapsulation can be
called as the core concept of OOP because it is encapsulation that reduces the maintenance burden, and
limiting your exposure to vulnerabilities. The programmer has to design a well-defined interface to
control the access of a particular code and data.
While working with procedural languages, it is not always clear which functions work on
which variables but object-oriented programming provides you framework to place the data and the
relevant functions together in the same object.
Encapsulation
Member Data
function member
Class
Encapsulation is not itself data hiding but it leads to data hiding. Wrapping similar data
members and functions inside a class help in data hiding and thus hides sensitive information and limit
access to the internal state only. So, encapsulation refers to bundling related fields and methods
together, which can be used to achieve data hiding.
Data Hiding
Data hiding is a software development technique specifically used in object-oriented
programming (OOP) to hide internal object details (data members). Data hiding ensures exclusive
data access to class members and protects object integrity by preventing unintended or intended
changes.
This insulation of the data from direct access by the program is called data hiding .
Abstraction at design level can be used to achieve data hiding.
A class groups its members into three sections : private , protected and public. The private and
protected members remain hidden from outside world. Thus through private and protected members, a
class enforces data hiding.
Data hiding guarantees the restricted access of data from unwanted sources and maintains data
integrity by preventing unintended or intended changes.
Data Abstraction
Data abstraction is one of the most essential and important features of object-oriented
programming in C++. Data abstraction refers to providing only essential information about the data to
the outside world, hiding the background details or implementation. For example s suppose you want
to sort a list of numbers in your Python program, so for that, you can make a call to the sort( ) function
without knowing what algorithm the function uses to sort the given values. So, it hides the unnecessary
internal details from the end-users and to make their task easier. Data Abstraction in Python can be
achieved by creating abstract classes.
Inheritance : The mechanism of deriving new class from old class is called Inheritance. The old
class is called Base class or super class or parent class and new one is called the derived class or
subclass or child class.The derived class inherits some or all the traits from the base class. It supports
the concept of hierarchical classification. In OOP , the concept of inheritance provides the idea of
reusability. This means we can add additional features to an existing class without modifying it. The
new class will have the combined features of both the classes. The real appeal and power of the
inheritance mechanism is that it allows the programmer to reuse a class that is almost, but not exactly ,
what he wants, and to tailor the class in such a way that it does not introduce any undesirable side
effects into the rest of classes.
Syntax :
Class Baseclass :
{ Body } # attributes and method definition
Class Derivedclass (Baseclass) :
{ Body } # attributes and method definition
Types of Inheritance :
A derived class with only one base class is called single inheritance.
A derived class with several base classes is called multiple inheritance.
The mechanism of deriving class from another derived class is known as multilevel
inheritance.
The process of deriving many classes from one base class is called hierarchical inheritance.
class Gfather:
def gname(self):
print("My Grand Father's name is : Kareem")
#The child class Father inherits the base class Gfather
class father(Gfather):
def fname(self):
print("My Father's name is : Hassan")
#The child class Son inherits another child class Father
class Son( Father):
def sname(self):
print("My name is : Shabeer...")
obj =Son( )
obj.gname( )
obj.fname( )
obj.sname( )
In the above example, we have derived a subclass Father from a superclass Gfather and then subclass
Son from subclass Father. We used object of subclass Son (obj) to access methods of superclass
Father and Gfather This is possible because the subclass Son inherits all attributes and methods of the
subclass Father , which itself inherited all attributes and methods of the superclass Gfather.
Polymorphism : Polymorphism is one of the crucial features of OOP. It simply means ‘One name ,
Multiple forms’. Polymorphism , is Greek term , means ability to take more than one form. It refers to
the ability to execute different operations in response to the same message.
Polymorphism plays an important role in allowing objects having different internal structures to
share the same external interface.
This means that a general class of operations may be accessed in the same manner through
specific actions associated with each operations may differ. The Polymorphism is extensively used in
implementing inheritance.
In object-oriented-based Python programming, Polymorphism means the same function name
is being used for different types. Each function is differentiated based on its data type and number of
arguments. So, each function has a different signature. This allows developers to write clean, readable,
and resilient codes. Polymorphism is supported in Python via method overriding and operator
overloading.
E.g def add( x,y)
print( x+ y )
add ( 10, 15) # call add( )and pass two integers
add (“ Haris”. “Ahmad”) # call add( )and pass two strings
When we call add function and pass two integers , the function displays 25. But when we pass two
strings , then same function concatenates or joins those strings. Since the function is exhibiting
different behavior , performing different tasks , it is said to exhibit polymorphism.
Access specifiers : Access modifiers (or access specifiers) are keywords in object-oriented
languages ( like C++ ) that set the accessibility of classes, methods, and other members. So, access
specifiers define how the members (attributes and methods) of a class can be accessed from outside the
class. Access specifiers in Python have an important role to play in securing data from unauthorized
access. Python supports three types of access modifiers which provide restrictions on the access of
member variables and methods of the class from any object outside the class.
Python provides conceptual implementation of public, protected, and private access modifiers, but not
like other languages like C#, Java, C++.
1. Public Access Modifier : All data members and member functions of a class are public by default,
which means they can be accessed from anywhere outside or inside the class. No public keyword is
required to make the class or methods public. Attributes or methods without any Underscore prefix
are considered public.
2. Private Access Modifier : Class members with private access modifier can only be accessed within
the class where they are defined and cannot be accessed outside the class. In Python data members are
declared by adding a prefix with two underscores(‘__’) before their declaration. Private access
modifier is the most secure access modifier.
3. Protected Access Modifier : Data members of a class are declared protected by adding a single
underscore ‘_’ symbol before the data member of that class. The members of a class that are declared
protected are only accessible within the class and to a class derived from it.
print (e1.name)
print (e1._salary)
print (e1.__age) # This line will give error as this attribute is private
OUTPUT :
Bhavana
10000
Constructor :
A constructor is a special type of method (function) which is invoked automatically when a class
object is created. So constructor initializes the attributes ( variables ) of the object with appropriate
values. So , there is no need to make a separate call to a member function for initialization of object. It
is called constructor because it constructs the values of data members of the class.
Syntax of constructor declaration :
In python constructor is defined by the _ _ init _ _( ) method ( with leading and two trailing
underscores .
def __init__(self, parameters):
#initialize instance variables
self.attributes1=parameter1
self.attributes2=parameter2
def __init__(self, parameters ) defines the constructor method named _ _init_ _( ) within a
class. The __init__( ) method as well as any instance method in a class has a mandatory
parameter, self followed by any other parameters we want to pass to initialize the object.
However, you can give any name to the first parameter, not necessarily self. The keyword self
represents the instance of a class and binds the attributes with the given arguments.
E.g : contructor1.py
class student:
def __init__( emp, n1, r1):
emp.name = n1 # declaring and initializing the ‘name’ attribute
emp.rollno= r1 # declaring and initializing the ‘rollno’ attribute
# creating an object
Advantages of Constructors :
1. Automatic Initialization : Python Constructors gives the guarantee that an object is automatically
initialized correctly as soon as it is created.
2. Code Reusability : You can reuse the initialization code across various class instances by declaring
a constructor.
3. Consistency : They minimize errors and inconsistencies by offering a consistent method of
initializing objects.
Types of constructors :
1. Default Constructor
2. Parameterized constructor
1. Default constructor : The Python constructor which does not accept any parameter other than
self , which is reference to the instance being created , is called as default constructor. Default
constructors are useful when you want to create an object with a predefined set of attributes (It is used
to create an object with default values for its attributes. ), but you don’t want to specify the values
of those attributes when the object is created.
Exp 1:
class Employee:
def __init__(self):
self.data = "Shows Default Data only"
employee1 = Employee( )
print(employee1.data) # Shows Default Data only
2. Parameterized constructor : The Python constructor which has multiple parameters along
with the self , which is reference to the instance being constructed , is called as Parameterized
constructor. Rest of the arguments are provided by the programmer.
Example :
class Employee:
'Common base class for all employees'
def __init__(self, name, age):
self.name = name
self.age = age
e1 = Employee(" Musavir", 18 )
e2 = Employee("Bariz ", 19)
OUTPUT :
Name: Musavir
age: 18
Name: Bariz
age: 19
Let's have a look at another scenario, what happen if we declare the two same constructors in the class.
Ex :
class Student:
def __init__(self):
print("The First Constructor")
def __init__(self):
print("The second contructor")
st = Student( )
OUTPUT :
The Second Constructor
In the above code, the object st called the second constructor whereas both have the same
configuration. The first method is not accessible by the st object. Internally, the object of the class will
always call the last constructor if the class has multiple constructors.
Destructor :
Destructors are called when an object gets destroyed. In Python, destructors are not needed as
much as in C++ because Python has a garbage collector that handles memory management
automatically.
The __del__( ) method is a known as a destructor method in Python. It is called when all references to
the object have been deleted i.e when an object is garbage collected.
destructor.py
class Student:
# Initializing
def __init__(self):
print('Student created.')
# Deleting (Calling destructor)
def __del__(self):
print('Destructor called, Student deleted.')
obj = Student()
print('Program End...')
del obj
Output :
Student created
Program End
Destructor called, Student deleted
Advantages of destructors:
Automatic cleanup: Destructors provide automatic cleanup of resources used by an object when
it is no longer needed. This can be especially useful in cases where resources are limited, or
where failure to clean up can lead to memory leaks or other issues.
Consistent behavior: Destructors ensure that an object is properly cleaned up, regardless of how
it is used or when it is destroyed. This helps to ensure consistent behavior and can help to prevent
bugs and other issues.
Easy to use: Destructors are easy to implement in Python, and can be defined using the __del__()
method.
Helps with debugging: Destructors can be useful for debugging, as they can be used to trace the
lifecycle of an object and determine when it is being destroyed.
Abstract class : An abstract class is a class for which one or more methods are declared but not
defined. An abstract method is a method that has a declaration but does not have an implementation.
Once an abstract class is defined, it ceases to be abstract and becomes a concrete class. Abstract
class cannot be used to create an object. When we create an object for the abstract class it raises an
error.
Concrete Class : Concrete Classes are regular classes, where all methods are completely
implemented. These classes can be instantiated, and are not abstract.
The self-parameter : The self-parameter refers to the current instance of the class and accesses
the class variables. We can use anything instead of self, but it must be the first parameter of any
function which belongs to the class.
The self-argument is the only one required by the __init__ method. This argument refers to the
newly generated instance of the class. To initialise the values of each attribute associated with the
objects, you can declare extra arguments in the __init__ method.
Note: self in Python is equivalent to this in C++ or Java.
All instances of a class exchange class variables. They function independently of any class
methods and may be accessed through the use of the class name or instance of class. They are used
to define the properties that are common to all instances of class.
Whereas, instance variables are specific to each instance of a class. They are specified
using the self-argument in the __init__ method. They are used to define the properties that are
unique to each instance of class.