Python Oops
Python Oops
Classes are created by keyword class. Attributes are the variables that belong to a class.
Attributes are always public and can be accessed using the dot(.) operator. Eg.:
Myclass.Myattribute
class ClassName:
# Statement-1
# Statement-N
Defining a class –
# Python3 program to
# demonstrate defining
# a class
class Dog:
pass
In the above example, the class keyword indicates that you are creating a class followed by the
name of the class (Dog in this case).
Class Objects
An object consists of :
State: It is represented by the attributes of an object. It also reflects the properties of an object.
Behavior: It is represented by the methods of an object. It also reflects the response of an object
to other objects.
Identity: It gives a unique name to an object and enables one object to interact with other
objects.
When an object of a class is created, the class is said to be instantiated. All the instances share
the attributes and the behavior of the class. But the values of those attributes, i.e. the state are
unique for each object. A single class may have any number of instances.
Example:
Declaring an object –
Python3
# Python3 program to
# demonstrate instantiating
# a class
class Dog:
# A simple class
# attribute
attr1 = "mammal"
attr2 = "dog"
# A sample method
def fun(self):
print("I'm a", self.attr1)
print("I'm a", self.attr2)
# Driver code
# Object instantiation
Rodger = Dog()
Output
mammal
I'm a mammal
I'm a dog
In the above example, an object is created which is basically a dog named Rodger. This class
only has two class attributes that tell us that Rodger is a dog and a mammal.
The self
Class methods must have an extra first parameter in the method definition. We do not give a
value for this parameter when we call the method, Python provides it.
If we have a method that takes no arguments, then we still have to have one argument.
This is similar to this pointer in C++ and this reference in Java.
When we call a method of this object as myobject.method(arg1, arg2), this is automatically
converted by Python into MyClass.method(myobject, arg1, arg2) – this is all the special self is
about.
__init__method
The __init__ method is similar to constructors in C++ and Java. Constructors are used to
initializing the object’s state. Like methods, a constructor also contains a collection of
statements(i.e. instructions) that are executed at the time of Object creation. It runs as soon as
an object of a class is instantiated. The method is useful to do any initialization you want to do
with your object.
Python3
# A Sample class with init method
class Person:
# Sample Method
def say_hi(self):
print('Hello, my name is', self.name)
p = Person('Nikhil')
p.say_hi()
Output
Hello, my name is Nikhil
Python3
# Python3 program to show that the variables with a value
# assigned in the class declaration, are class variables and
# variables inside methods and constructors are instance
# variables.
# Class Variable
animal = 'dog'
# Instance Variable
self.breed = breed
self.color = color
print('Rodger details:')
print('Rodger is a', Rodger.animal)
print('Breed: ', Rodger.breed)
print('Color: ', Rodger.color)
print('\nBuzo details:')
print('Buzo is a', Buzo.animal)
print('Breed: ', Buzo.breed)
print('Color: ', Buzo.color)
Output
Rodger details:
Rodger is a dog
Breed: Pug
Color: brown
Buzo details:
Buzo is a dog
Breed: Bulldog
Color: black
Python3
# Python3 program to show that we can create
# instance variables inside methods
# Class Variable
animal = 'dog'
# Instance Variable
self.breed = breed
# Driver Code
Rodger = Dog("pug")
Rodger.setColor("brown")
print(Rodger.getColor())
Output
Brown
Types of constructors :
Default constructor: The default constructor is a simple constructor which doesn’t accept
any arguments. Its definition has only one argument which is a reference to the instance being
constructed.
________________________________________________________
MODULE 3: Destructors in Python
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.
Note : A reference to objects is also deleted when the object goes out of reference or when the
program ends.
Example 1 : Here is the simple example of destructor. By using del keyword we deleted the all
references of object ‘obj’, therefore destructor invoked automatically.
Note : The destructor was called after the program ended or when all the references to object are
deleted i.e when the reference count becomes zero, not when object went out of scope.
Example 2 :This example gives the explanation of above mentioned note. Here, notice that the
destructor is called after the ‘Program End…’ printed.
Example 3 : Now, consider the following example
In this example when the function fun() is called, it creates an instance of class B which passes itself
to class A, which then sets a reference to class B and resulting in a circular reference.
Generally, Python’s garbage collector which is used to detect these types of cyclic references would
remove it but in this example the use of custom destructor marks this item as “uncollectable”.
Simply, it doesn’t know the order in which to destroy the objects, so it leaves them. Therefore, if your
instances are involved in circular references they will live in memory for as long as the application
run.
Python
# code
# A Python program to demonstrate inheritance
class Person(object):
# Constructor
def __init__(self, name):
self.name = name
# To get name
def getName(self):
return self.name
class Employee(Person):
# Here we return true
def isEmployee(self):
return True
# Driver code
emp = Person("Geek1") # An Object of Person
print(emp.getName(), emp.isEmployee())
Output
('Geek1', False)
('Geek2', True)
A child class needs to identify which class is its parent class. This can be done by mentioning
the parent class name in the definition of the child class.
Python
# Python code to demonstrate how parent constructors
# are called.
# parent class
class Person(object):
def display(self):
print(self.name)
print(self.idnumber)
# child class
class Employee(Person):
def __init__(self, name, idnumber, salary, post):
self.salary = salary
self.post = post
Output:
Rahul
886012
‘a’ is the instance created for the class Person. It invokes the __init__() of the referred class.
You can see ‘object’ written in the declaration of the class Person. In Python, every class
inherits from a built-in basic class called ‘object’. The constructor i.e. the ‘__init__’ function
of a class is invoked when we create an object variable or an instance of the class.
The variables defined within __init__() are called as the instance variables or objects. Hence,
‘name’ and ‘idnumber’ are the objects of the class Person. Similarly, ‘salary’ and ‘post’ are the
objects of the class Employee. Since the class Employee inherits from class Person, ‘name’
and ‘idnumber’ are also the objects of class Employee.
If you forget to invoke the __init__() of the parent class then its instance variables would not
be available to the child class.
class A:
def __init__(self, n='Rahul'):
self.name = n
class B(A):
def __init__(self, roll):
self.roll = roll
object = B(23)
print(object.name)
Output :
Traceback (most recent call last):
File "/home/de4570cca20263ac2c4149f435dba22c.py", line 12, in
print (object.name)
AttributeError: 'B' object has no attribute 'name'
1. Single inheritance: When a child class inherits from only one parent class, it is called single
inheritance. We saw an example above.
2. Multiple inheritance: When a child class inherits from multiple parent classes, it is called
multiple inheritance.
Python
# Python example to show the working of multiple
# inheritance
class Base1(object):
def __init__(self):
self.str1 = "Geek1"
print("Base1")
class Base2(object):
def __init__(self):
self.str2 = "Geek2"
print("Base2")
print("Derived")
def printStrs(self):
print(self.str1, self.str2)
ob = Derived()
ob.printStrs()
Output
Base1
Base2
Derived
Python
# A Python program to demonstrate inheritance
class Base(object):
# Constructor
def __init__(self, name):
self.name = name
# To get name
def getName(self):
return self.name
# Constructor
def __init__(self, name, age):
Base.__init__(self, name)
self.age = age
# To get name
def getAge(self):
return self.age
class GrandChild(Child):
# Constructor
def __init__(self, name, age, address):
Child.__init__(self, name, age)
self.address = address
# To get address
def getAddress(self):
return self.address
# Driver code
g = GrandChild("Geek1", 23, "Noida")
print(g.getName(), g.getAge(), g.getAddress())
Output
Geek1 23 Noida
4. Hierarchical inheritance : More than one derived classes are created from a single base.
5. Hybrid inheritance: This form combines more than one form of inheritance. Basically, it
is a blend of more than one type of inheritance.
Private members of parent class
We don’t always want the instance variables of the parent class to be inherited by the child
class i.e. we can make some of the instance variables of the parent class private, which won’t
be available to the child class.
We can make an instance variable by adding double underscores before its name. For example,
Python
# Python program to demonstrate private members
# of the parent class
class C(object):
def __init__(self):
self.c = 21
class D(C):
def __init__(self):
self.e = 84
C.__init__(self)
object1 = D()
Output :
File "/home/993bb61c3e76cda5bb67bd9ea05956a1.py", line 16, in
print (object1.d)
AttributeError: type object 'D' has no attribute 'd'
Since ‘d’ is made private by those underscores, it is not available to the child class ‘D’ and
hence the error.
Types of Inheritance
Types of Inheritance depends upon the number of child and parent classes involved. There are
four types of inheritance in Python:
Single Inheritance :Single inheritance enables a derived class to inherit properties from a
single parent class, thus enabling code reusability and the addition of new features to existing
code.
Example:
Python
# Python program to demonstrate
# 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.")
# Driver's code
object = Child()
object.func1()
object.func2()
Multiple Inheritance : When a class can be derived from more than one base class this typeof
inheritance is called multiple inheritance. In multiple inheritance, all the features of the base
classes are inherited into the derived class.
Example:
Python3
# code
# Python program to demonstrate
# multiple inheritance
# Base class1
class Mother:
mothername = ""
def mother(self):
print(self.mothername)
# Base class2
class Father:
fathername = ""
def father(self):
print(self.fathername)
# Derived class
# Driver's code
s1 = Son()
s1.fathername = "RAM"
s1.mothername = "SITA"
s1.parents()
Output:
Father : RAM
Mother : SITA
Multilevel Inheritance
In multilevel inheritance, features of the base class and the derived class are further inherited
into the new derived class. This is similar to a relationship representing a child and grandfather.
Example:
Python
# code
# Python program to demonstrate
# multilevel inheritance
# Base class
class Grandfather:
# Intermediate class
class Father(Grandfather):
def __init__(self, fathername, grandfathername):
self.fathername = fathername
# invoking constructor of Grandfather class
Grandfather.__init__(self, grandfathername)
# Derived class
class Son(Father):
def __init__(self, sonname, fathername, grandfathername):
self.sonname = sonname
def print_name(self):
print('Grandfather name :', self.grandfathername)
print("Father name :", self.fathername)
print("Son name :", self.sonname)
# Driver code
s1 = Son('Prince', 'Rampal', 'Lal mani')
print(s1.grandfathername)
s1.print_name()
Hierarchical Inheritance : When more than one derived classes are created from a single base
this type of inheritance is called hierarchical inheritance. In this program, we have a parent
(base) class and two child (derived) classes.
Example:
Python
# Python program to demonstrate
# Hierarchical inheritance
# Base class
class Parent:
def func1(self):
print("This function is in parent class.")
# Derived class1
class Child1(Parent):
def func2(self):
print("This function is in child 1.")
# Derivied class2
class Child2(Parent):
def func3(self):
print("This function is in child 2.")
# Driver's code
object1 = Child1()
object2 = Child2()
object1.func1()
object1.func2()
object2.func1()
object2.func3()
Example:
Python
# code
# Python program to demonstrate
# hybrid inheritance
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.")
# Driver's code
object = Student3()
object.func1()
object.func2()
Encapsulation in Python
Encapsulation is one of the fundamental concepts in object-oriented programming (OOP). It
describes the idea of wrapping data and the methods that work on data within one unit. This puts
restrictions on accessing variables and methods directly and can prevent the accidental modification
of data. To prevent accidental change, an object’s variable can only be changed by an object’s
method. Those types of variables are known as private variables.
A class is an example of encapsulation as it encapsulates all the data that is member functions,
variables, etc.
Consider a real-life example of encapsulation, in a company, there are different sections like the
accounts section, finance section, sales section etc. The finance section handles all the financial
transactions and keeps records of all the data related to finance. Similarly, the sales section handles all
the sales-related activities and keeps records of all the sales. Now there may arise a situation when for
some reason an official from the finance section needs all the data about sales in a particular month. In
this case, he is not allowed to directly access the data of the sales section. He will first have to contact
some other officer in the sales section and then request him to give the particular data. This is what
encapsulation is. Here the data of the sales section and the employees that can manipulate them are
wrapped under a single name “sales section”. Using encapsulation also hides the data. In this
example, the data of the sections like sales, finance, or accounts are hidden from any other section.
Protected members
Protected members (in C++ and JAVA) are those members of the class that cannot be accessed
outside the class but can be accessed from within the class and its subclasses. To accomplish this in
Python, just follow the convention by prefixing the name of the member by a single underscore “_”.
Although the protected variable can be accessed out of the class as well as in the derived
class(modified too in derived class), it is customary(convention not a rule) to not access the protected
out the class body.
Note: The __init__ method is a constructor and runs as soon as an object of a class is instantiated.
Private members
Private members are similar to protected members, the difference is that the class members declared
private should neither be accessed outside the class nor by any base class. In Python, there is no
existence of Private instance variables that cannot be accessed except inside a class.
However, to define a private member prefix the member name with double underscore “__”.
Note:Python’s private and protected members can be accessed outside the class through python name
mangling.
Polymorphism in Python
What is Polymorphism : The word polymorphism means having many forms. In
programming, polymorphism means the same function name (but different signatures) being
used for different types.
Example of inbuilt polymorphic functions :
Python
# Python program to demonstrate in-built poly-
# morphic functions
Output:
5
3
Python
# code
# A simple Python function to demonstrate
# Polymorphism
# Driver code
print(add(2, 3))
print(add(2, 3, 4))
Output
5
9
Output:
5
9
Python
class India():
def capital(self):
print("New Delhi is the capital of India.")
def language(self):
print("Hindi is the most widely spoken language of India.")
def type(self):
print("India is a developing country.")
class USA():
def capital(self):
print("Washington, D.C. is the capital of USA.")
def language(self):
print("English is the primary language of USA.")
def type(self):
print("USA is a developed country.")
obj_ind = India()
obj_usa = USA()
for country in (obj_ind, obj_usa):
country.capital()
country.language()
country.type()
Output:
New Delhi is the capital of India.
Hindi is the most widely spoken language of India.
India is a developing country.
Washington, D.C. is the capital of USA.
English is the primary language of USA.
USA is a developed country.
Python
class Bird:
def intro(self):
print("There are many types of birds.")
def flight(self):
print("Most of the birds can fly but some cannot.")
class sparrow(Bird):
def flight(self):
print("Sparrows can fly.")
class ostrich(Bird):
def flight(self):
print("Ostriches cannot fly.")
obj_bird = Bird()
obj_spr = sparrow()
obj_ost = ostrich()
obj_bird.intro()
obj_bird.flight()
obj_spr.intro()
obj_spr.flight()
obj_ost.intro()
obj_ost.flight()
Output:
There are many types of birds.
Most of the birds can fly but some cannot.
There are many types of birds.
Sparrows can fly.
There are many types of birds.
Ostriches cannot fly.
Python
def func(obj):
obj.capital()
obj.language()
obj.type()
obj_ind = India()
obj_usa = USA()
func(obj_ind)
func(obj_usa)
Code: Implementing Polymorphism with a Function
Python
class India():
def capital(self):
print("New Delhi is the capital of India.")
def language(self):
print("Hindi is the most widely spoken language of India.")
def type(self):
print("India is a developing country.")
class USA():
def capital(self):
print("Washington, D.C. is the capital of USA.")
def language(self):
print("English is the primary language of USA.")
def type(self):
print("USA is a developed country.")
def func(obj):
obj.capital()
obj.language()
obj.type()
obj_ind = India()
obj_usa = USA()
func(obj_ind)
func(obj_usa)
Output:
New Delhi is the capital of India.
Hindi is the most widely spoken language of India.
India is a developing country.
Washington, D.C. is the capital of USA.
English is the primary language of USA.
USA is a developed country.
A class method receives the class as an implicit first argument, just like an instance method receives
the instance
Syntax:
Static Method
A static method does not receive an implicit first argument.
Syntax:
A static method is also a method that is bound to the class and not the object of the class.
A static method can’t access or modify the class state.
It is present in a class because it makes sense for the method to be present in class.
1. A class method takes cls as the first parameter while a static method needs no specific
parameters.
2. A class method can access or modify the class state while a static method can’t access or
modify it.
3. In general, static methods know nothing about the class state. They are utility-type methods
that take some parameters and work upon those parameters. On the other hand class methods
must have class as a parameter.
4. We use @classmethod decorator in python to create a class method and we use
@staticmethod decorator to create a static method in python.
Let us look at an example to understand the difference between both of them. Let us say we
want to create a class Person. Now, python doesn’t support method overloading like C++ or
Java so we use class methods to create factory methods. In the below example we use a class
method to create a person object from birth year.
As explained above we use static methods to create utility functions. In the below example we
use a static method to check if a person is an adult or not.
Implementation
Python
# Python program to demonstrate
# use of class method and static method.
from datetime import date
class Person:
self.name = name
self.age = age
@classmethod
def fromBirthYear(cls, name, year):
@staticmethod
def isAdult(age):
return age > 18
print(person1.age)
print(person2.age)
Output:
21
25
True