Oopps
Oopps
MODULE – IV
Agenda:
Instances,Instance Attributes
Composition
Inheritance
Privacy,
Class
Object
Method
Inheritance
Polymorphism
Data Abstraction
Encapsulation
Class:
A Class in Python is a logical grouping of data and functions. It gives the freedom to
create data structures that contains arbitrary content and hence easily accessible.
A class is a "blueprint" or "prototype" to define an object. Every object has its
properties and methods. That means a class contains some properties and methods.
A class is the blueprint from which the individual objects are created. Class is
composed of three things: a name, attributes, and operations
For example: if you have an employee class, then it should contain an attribute and
method, i.e. an email id, name, age, salary, etc.
Syntax
class ClassName:
<statement-1>
.
.
<statement-N>
Object
An object (instance) is an instantiation of a class. When class is defined, only the
description for the object is defined. Therefore, no memory or storage is allocated.
Object is composed of three things: a name, attributes, and operations or Objects are
an instance of a class. It is an entity that has state and behavior.
Syntax: object_name = ClassName(arguments)
Types of Constructors:
We observe three types of Python Constructors, two of which are in our hands. Let‟s begin
with the one that isn‟t.
Default Constructor
Non- Parameterized Constructor
Parameterized Constructor
Default Constructor:
A constructor that Python lends us when we forget to include one. This one does absolutely
nothing but instantiates the object; it is an empty constructor- without a body.
Example:
class defaultConstructor:
def display(self):
print("This is Default Constructor")
dc=defaultConstructor()
dc.display()
OutPut:
This is Default Constructor
Non- Parameterized Constructor:
When we want a constructor to do something but none of that is to manipulate
values, we can use a non-parameterized constructor.
As we know that a constructor always has a name init and the name init is prefixed
and suffixed with a double underscore(__). We declare a constructor using def
keyword, just like methods.
OutPut:
Non- Parameterized Constructor
Name= Raj
Parameterized constructor:
Constructor with parameters is known as parameterized constructor.The
parameterized constructor take its first argument as a reference to the instance being
constructed known as self and the rest of the arguments are provided by the
programmer.
Example:
class Addition:
first = 0
second = 0
answer = 0
def __init__(self, f, s):
self.first = f
self.second = s
def display(self):
print("First number = " + str(self.first))
print("Second number = " + str(self.second))
print("Addition of two numbers = " + str(self.answer))
def calculate(self):
self.answer = self.first + self.second
obj = Addition(1000, 2000)
obj.calculate()
obj.display()
OutPut:
First number = 1000
Second number = 2000
Addition of two numbers = 3000
Attributes are noting but variables we the following types are there in python.
Types of Class Variables in Python: There are three different types of variables in
OOPs in python.
Instance variables (object level variables)
Static variables (class level variables)
Local variables
Instance Variables in Python:
If the value of a variable is changing from object to object then such variables are called as
instance variables.
class Student:
def __init__(self, name, id):
self.name=name
self.id=id
s1=Student('Srav', 1)
s2=Student('Raj', 2)
print("Studen1 info:")
print("Name: ", s1.name)
print("Id : ", s1.id)
print("Studen2 info:")
print("Name: ",s2.name)
print("Id : ",s2.id)
OutPut:
Studen1 info:
Name: Srav
Id : 1
Studen2 info:
Name: Raj
Id : 2
Static variables in Python:
If the value of a variable is not changing from object to object, such types of variables
are called static variables or class level variables. We can access static variables either
by class name or by object name. Accessing static variables with class names is
highly recommended than object names.
Example:
class Student:
college='MREC'
def __init__(self, name, id):
Studen2 info:
Name: RAJ
Id : 2
College name : MREC
Local Variables in Python:
The variable which we declare inside of the method is called a local variable.
Generally, for temporary usage we create local variables to use within the methods.
The scope of these variables is limited to the method in which they are declared.
They are not accessible out side of the methods.
Example:
class mrec:
dept="DS"#static variable
def display(self):
dept="CSE" #Local Variable
print(dept)
d=mrec()
d.display()
print(d.dept)
OutPut:
CSE
DS
Instance methods:
Instance methods are the most common type of methods in Python classes. These
are so called because they can access unique data of their instance.
And we call it as default method in python.
If you have two objects each created from a car class, then they each may have
different properties. They may have different colors, engine sizes, seats, and so on.
Instance methods are methods which act upon the instance variables of the class.
They are bound with instances or objects, that”s why called as instance methods.
The first parameter for instance methods should be self variable which refers to
instance. Along with the self variable it can contain other variables as well.
Any method you create will automatically be created as an instance method, unless
you tell Python otherwise.
Example:
class Test:
def __init__(self, a, b):
self.a = a
self.b = b
def avg(self):
return (self.a + self.b) / 2
s1 = Test(10, 20)
print( s1.avg() )
OutPut:
15.0
Class Methods:
Class methods are methods which act upon the class variables or static variables of
the class. We can go for class methods when we are using only class variables (static
variables) within the method.
Class methods should be declared with @classmethod.
Just as instance methods have „self‟ as the default first variable, class method should
have „cls‟ as the first variable. Along with the cls variable it can contain other
variables as well.
Class methods are rarely used in python
class Mrec:
Dept="CSE"
def Dept_name(self,name):
print("Instance method=",name)
@classmethod
def get_Dept(cls):
return cls.Dept
m=Mrec()
m.Dept_name("DS")
print("Class method=",Mrec.get_Dept())
OutPut:
Instance method= DS
Class method= CSE
Static methods
A static method can be called without an object for that class, using the class name
directly. If you want to do something extra with a class we use static methods.
Inside these methods we won‟t use any instance or class variables. No arguments like
cls or self are required at the time of declaration.
We can declare static method explicitly by using @staticmethod decorator.
We can access static methods by using class name or object reference
Example:
class Demo:
@staticmethod
def sum(x, y):
print(x+y)
@staticmethod
def multiply(x, y):
print(x*y)
Demo.sum(2, 3)
Demo.multiply(2,4)
OutPut:
5
8
Sum= 15
Sub= 5
Mul= 50
Inheritance or Is-A Relation in Python
The inheritance is the process of acquiring the properties of one class to another
class.
Inheritance in python programming is the concept of deriving a new class from an
existing class.
Using the concept of inheritance we can inherit the properties of the existing class to
our new class.
The new derived class is called the child class and the existing class is called the
parent class.
The Parent class is the class which provides features to another class. The parent
class is also known as Base class or Superclass.
The Child class is the class which receives features from another class. The child
class is also known as the Derived Class or Subclass.
Advantages of Inheritance:
Code reusability- we do not have to write the same code again and again, we can
Example
class Parent:
def func1(self):
print("This function is in parent class.")
class Child(Parent):
def func2(self):
print("This function is in child class.")
object = Child()
object.func1()
object.func2()
OutPut:
This function is in parent class.
This function is in child class.
Multi-Level Inheritance
In this type of inheritance, the child class derives from a class which already derived
from another class. Look at the following example code.
Example:
class Parent:
def func1(self):
print('this is function 1')
class Child(Parent):
def func2(self):
print('this is function 2')
class Child2(Child):
def func3(self):
print('this is function 3')
ob = Child2()
ob.func1()
ob.func2()
ob.func3()
OutPut:
this is function 1
this is function 2
this is function 3
Example:
class Parent:
def func1(self):
print("This function is in parent class.")
class Child1(Parent):
def func2(self):
print("This function is in child 1.")
class Child2(Parent):
def func3(self):
print("This function is in child 2.")
object1 = Child1()
object2 = Child2()
object1.func1()
object1.func2()
object2.func1()
object2.func3()
OutPut:
This function is in parent class.
This function is in child 1.
This function is in parent class.
This function is in child 2.
Multiple Inheritance:
When child class is derived or inherited from the more than one parent classes. This is
called multiple inheritance. In multiple inheritance, we have two parent classes/base classes
and one child class that inherits both parent classes‟ properties.
Example:
class Father:
fathername = ""
def father(self):
print(self.fathername)
class Mother:
mothername = ""
def mother(self):
print(self.mothername)
Hybrid Inheritance:
Hybrid inheritance satisfies more than one form of inheritance ie. It may be consists of all
types of inheritance that we have done above. It is not wrong if we say Hybrid Inheritance is
the combinations of simple, multiple, multilevel and hierarchical inheritance. This type of
inheritance is very helpful if we want to use concepts of inheritance without any limitations
according to our requirements.
Example:
class School:
def func1(self):
print("This function is in school.")
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.")
class A:
def __init__(self):
print("super class A constructor")
class B(A):
def __init__(self):
print("Child class B constructor")
super().__init__()
b=B()
OutPut:
Child class B constructor
super class A constructor
2. Calling super class method from child class method using super()
class A:
def m1(self):
print("Super class A: m1 method")
class B(A):
def m1(self):
print("Child class B: m1 method")
super().m1()
b=B()
b.m1()
Output:
Child class B: m1 method
Super class A: m1 method
3. Calling super class variable from child class method using super()
class A:
x=10
def m1(self):
print("Super class A: m1 method")
Output:
Child class x variable 20
Super class x variable 10
Composition (Has A Relation):
Syntax:
class A :
# variables of class B
# methods of class B
...
...
Example:
class Component:
def __init__(self):
print('Component class object created...')
def m1(self):
print('Component class m1() method executed...')
class Composite:
def __init__(self):
self.obj1 = Component()
print('Composite class object also created...')
def m2(self):
print('Composite class m2() method executed...')
self.obj1.m1()
obj2 = Composite()
obj2.m2()
OutPut:
Component class object created...
Composite class object also created...
Composite class m2() method executed...
Component class m1() method executed...
In most of the object-oriented languages access modifiers are used to limit the access
to the variables and functions of a class. Most of the languages use three types of
access modifiers, they are –
Private
Public
Example:
class Student:
def __init__(self, name, dept):
self.__name = name # private
self.__dept = dept # private
s1=Student("Raj","CSE")
print("Name=",s1.__name)
print("Dept=",s1.__dept)
OutPut: error
protected Access Modifier:
Protected variables or we can say protected members of a class are restricted to be
used only by the member functions and class members of the same class. And also it
can be accessed or inherited by its derived class ( child class ).
We can modify the values of protected variables of a class. The syntax we follow to
make any variable protected is to write variable name followed by a single
underscore (_) ie. _varName.
Example:
class Student:
def __init__(self, name, dept):
self._name = name # Protected
self._dept = dept #Protected
class Stu(Student):
pass
s1=Student("Raj","CSE")
print("Name=",s1._name)
print("Dept=",s1._dept)
s2=Stu("Srav","DS")
print("Name=",s2._name)
print("Dept=",s2._dept)
OutPut:
Name= Raj
Dept= CSE
Name= Srav
Dept= DS
Example:
class methodOverride2(methodOverride1):
def display(self):
print("method invoked from derived class")
ob=methodOverride2()
ob.display()
OutPut:
method invoked from derived class
Built in Functions for Classes, Instances, and Other Objects,
In Python we have different typed of built in functions in Python.
1. hasattr() Function
The python hasattr() function returns true if an object has given named attribute.
Otherwise, it returns false.
Syntax: hasattr(object, attribute)
Parameters
object: It is an object whose named attribute is to be checked.
attribute: It is the name of the attribute that you want to search.
Return:It returns true if an object has given named attribute. Otherwise, it returns
false.
Example:
class Demo:
name="raj"
dept="CSE"
obj=Demo()
print(hasattr(Demo,'name'))
print(hasattr(Demo,'rollno'))
OutPut:
True
False
2. getattr() Function
The python getattr() function returns the value of a named attribute of an
object. If it is not found, it returns the default value.
Syntax: getattr(object, attribute, default)
Parameters:
class Demo:
name=""
dept=""
id=0
def __init__(self,name,dept,id):
self.name=name
self.dept=dept
self.id=id
obj=Demo("Raj","CSE",1)
print(obj.name)
print(obj.dept)
print(obj.id)
Example:
class A:
pass
class B(A):
pass
b=B()
print("b is an instance of the class B:",isinstance(b,B))
print("B is sub class of A Class:",issubclass(B,A))
OutPut:
b is an instance of the class B: True
B is sub class of A Class: True
Types vs. Classes/Instances:
When copied Two different variables is created along with Two reference variable is
different assignment even though the both created but both are pointing
variables having the same address if they are to the same object on the heap
pointing the same value
When Change does not reflect in the original ones. Changes reflected in the
changes are original ones.
made in the
copied
variable
Default value Primitive datatypes having the default value No default value for the
like 0 for int 0.0 for float etc. reference variable which is
created for a class
self.a=a
output: obj=A(10)
output:
Delegation is the mechanism through which an actor assigns a task or part of a task
to another actor. This is not new in computer science, as any program can be split
into blocks and each block generally depends on the previous ones. Furthermore,
code can be isolated in libraries and reused in different parts of a program,
implementing this "task assignment". In an OO system the assignee is not just the
code of a function, but a full-fledged object, another actor.
The main concept to retain here is that the reason behind delegation is code reuse.
We want to avoid code repetition, as it is often the source of regressions; fixing a bug
class Dept:
def __init__(self,insem,endsem):
self.insem=insem
self.endsem=endsem
def marks(self):
return self.insem+self.endsem
class student:
def __init__(self,sname,year,insem,endsem):
self.sname=sname
self.year=year
self.obj_Dept=Dept(insem,endsem)
def tmarks(self):
print("The Total Marks of %s"
%self.sname,self.obj_Dept.marks())
s=student('Raj','First',20,65)
s.tmarks()
OutPut:
The Total Marks of Raj 85