You are on page 1of 28

Class

A class is the building block that leads to Object-Oriented Programming. It is a user-de:ned


data type, that holds its own data members and member functions, which can be accessed
and used by creating an instance of that class. It is the blueprint of any object. Once we have
written a class and de:ned it, we can use it to create as many objects based on that class as
we want.

For example, consider the Class of Accounts. There may be many accounts with different
names and types, but all of them will share some common properties, as all of them will
have some common attributes like balance, account holder name, etc. So here, the Account
is the class.

Syntax:

class ClassName:

# Statement

Object
Object is an instance of a class. All data members and member functions of the class can be
accessed with the help of objects. When a class is de:ned, no memory is allocated, but
memory is allocated when it is instantiated (i.e. an object is created). For Example,
considering the objects for the class Account are SBI Account, ICICI account, etc. An object
consists of:

State: It is represented by the attributes of an object. It also reMects the properties of an


object.

Behavior: It is represented by the methods of an object. It also reMects 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.

Syntax:

obj = ClassName()

print(obj.atrr)
#Create a class named MyClass, with a property named x
class MyClass:
x = 5

#Create an object named p1, and print the value of x


p1 = MyClass()
print(p1.x)

Constructor
Constructors are generally used for instantiating an object. The task of constructors is to
initialize(assign values) to the data members of the class when an object of the class is
created. In Python the init() method is called the constructor and is always called when an
object is created.

Syntax:

def init(self): body of the constructor

Types of constructors :

Default constructor: The default constructor is a simple constructor which doesn’t accept
any arguments. Its de:nition has only one argument which is a reference to the instance
being constructed.

Parameterized constructor: constructor with parameters is known as parameterized


constructor. The parameterized constructor takes its :rst argument as a reference to the
instance being constructed known as self and the rest of the arguments are provided by the
programmer.

init()

Use the init() function to assign values to object properties, or other operations that are
necessary to do when the object is being created.

Self represents the instance of the class. By using the “self” we can access the attributes
and methods of the class in Python. It binds the attributes with the given arguments. The
self parameter is a reference to the current instance of the class, and is used to access
variables that belong to the class. It does not have to be named self , you can call it whatever
you like, but it has to be the :rst parameter of any function in the class
class ABC:

# default constructor
def __init__(self):
self.abc = "Hello"

# a method for printing data members


def print_Abc(self):
print(self.abc)

# creating object of the class


obj = ABC()

# calling the instance method using the object obj


obj.print_Abc()

Hello

#Create a class named Person, use the __init__() function to assign values for name
class Person:
def __init__(self, name, age):
self.name = name
self.age = age

p1 = Person("ABC", 36)

print(p1.name)
print(p1.age)

ABC
36

#use abc and xyz instead of self


class Person:
def __init__(abc, name, age):
abc.name = name
abc.age = age

def myfunc(xyz):
print("Hello my name is " + xyz.name)

p1 = Person("Python", 36)
p1.myfunc()

Hello my name is Python


Python built in class functions

1. getattr(obj,name,default): It is used to access the attribute of the object.


2. setattr(obj, name,value): It is used to set a particular value to the speci:c attribute of
an object.
3. delattr(obj, name): It is used to delete a speci:c attribute.
4. hasattr(obj, name): It returns true if the object contains some speci:c attribute.
class Student:
def __init__(self, name, id, age):
self.name = name
self.id = id
self.age = age

# creates the object of the class Student


s = Student("Bran", 101, 22)

# prints the attribute name of the object


print(getattr(s, 'name'))

# reset the value of attribute age to 23


setattr(s, 'age', 23)

# prints the modified value of age


print(getattr(s, 'age'))

# prints true if the student contains the attribute with name id


print(hasattr(s, 'id'))
# deletes the attribute age
delattr(s, 'age')

# this will give an error since the attribute age has been deleted
print(s.age)

Bran
23
True
--------------------------------------------------------------------------
-
AttributeError Traceback (most recent call
last)
<ipython-input-6-2c2533998703> in <cell line: 25>()
23
24 # this will give an error since the attribute age has been deleted
---> 25 print(s.age)

AttributeError: 'Student' object has no attribute 'age'

SEARCH STACK OVERFLOW

Class de:nitions cannot be empty, but if you for some reason have a class de:nition with no
content, put in the pass statement to avoid getting an error.

class Person:
pass
Built in class attributes

1. dict: It provides the dictionary containing the information about the class namespace.
2. doc: It contains a string which has the class documentation
3. name: It is a special variable which stores the name of the currently running Python
script or module.
4. module: It is used to access the module in which, this class is de:ned.
5. bases: It contains a tuple including all base classes.

class Student:
"""This is a student class"""
def __init__(self,name,id,age):
self.name = name;
self.id = id;
self.age = age
def display_details(self):
print("Name:%s, ID:%d, age:%d"%(self.name,self.id))
s = Student("Bran",101,22)
print(s.__doc__)
print(s.__dict__)
print(s.__module__)
print(__name__)

This is a student class


{'name': 'Bran', 'id': 101, 'age': 22}
__main__
__main__

str() method

Python has a particular method called str(). that is used to de:ne how a class object should
be represented as a string. It is often used to give an object a human-readable textual
representation, which is helpful for logging, debugging, or showing users object information.
When a class object is used to create a string using the built-in functions print() and str(), the
str() function is automatically used. You can alter how objects of a class are represented in
strings by de:ning the str() method.
class employee:
def __init__(self, name, company):
self.name = name
self.company = company

def __str__(self):
return f"My name is {self.name} and I work in {self.company}."

my_obj = employee("John", "Google")


print(my_obj)

My name is John and I work in Google.

Destructor
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.

Syntax:

def del(self): body of destructor

In Python, destructors are not needed as much as in C++ because Python has a garbage
collector that handles memory management automatically.

# Python program to illustrate destructor


class Employee:

# Initializing
def __init__(self):
print('Employee created.')

# Deleting (Calling destructor)


def __del__(self):
print('Destructor called, Employee deleted.')

obj = Employee()
del obj

Employee created.
Destructor called, Employee deleted.
Python Inheritance
Inheritance is the capability of one class to derive or inherit the properties from another
class. The class that derives properties is called the derived class or child class and the
class from which the properties are being derived is called the base class or parent class.
The bene:ts of inheritance are:

It represents real-world relationships well.

It provides the reusability of a code. We don’t have to write the same code again and again.
Also, it allows us to add more features to a class without modifying it.

It is transitive in nature, which means that if class B inherits from another class A, then all
the subclasses of B would automatically inherit from class A.

Syntax:

class derived-class(base class):

<class - suite>

Types of Inheritance

1. Single Inheritance: Single-level inheritance enables a derived class to inherit


characteristics from a single-parent class.
2. Multilevel Inheritance: Multi-level inheritance enables a derived class to inherit
properties from an immediate parent class which in turn inherits properties from his
parent class.
3. Hierarchical Inheritance: Hierarchical-level inheritance enables more than one derived
class to inherit properties from a parent class.
4. Multiple Inheritance: Multiple-level inheritance enables one derived class to inherit
properties from more than one base class.
class Person:
def __init__(self, fname, lname):
self.firstname = fname
self.lastname = lname

def printname(self):
print(self.firstname, self.lastname)

#Use the Person class to create an object, and then execute the printname method

x = Person("Bran", "White")
x.printname()

#child class Student created using base class Person


class Student(Person):
pass

#Use the Student class to create an object, and then execute the printname method
x = Student("Mike", "Rhyes")
x.printname()

Bran White
Mike Rhyes

Python also has a super() function that will make the child class inherit all the methods and
properties from its parent. By using the super() function, you do not have to use the name of
the parent element, it will automatically inherit the methods and properties from its parent.

#Add a method called welcome to the Student class

#Add the __init__() function to the Student class


#The child's __init__() function overrides the inheritance of the parent's __init__
class Student(Person):
def __init__(self, fname, lname, year):
super().__init__(fname, lname)
self.graduationyear = year

def welcome(self):
print("Welcome", self.firstname, self.lastname, "to the class of", self.graduat

x = Student("Mike", "Rhyes", 2025)


x.welcome()

Welcome Mike Rhyes to the class of 2025


Multi-level Inheritance
class class1:
<class - suite>
class class2(class1):
<class - suite>
class class3(class2):
<class - suite>
.
.

class Human:
def speak(self):
print("Human Speaking")
#The child class Male inherits the base class Human
class Man(Human):
def run(self):
print("Man running")
#The child class Boy inherits another child class Man
class Boy(Man):
def eat(self):
print("Boy Eating bread...")
d = Boy()
d.run()
d.speak()
d.eat()

Man running
Human Speaking
Boy Eating bread...
Multiple Inheritance
class Base1:
<class - suite>

class Base2:
<class - suite>
.
.
.
class BaseN:
<class - suite>

class Derived(Base1, Base2, ...... BaseN):


<class - suite>

class Mammal:
def mammal_info(self):
print("Mammals can give direct birth.")

class WingedAnimal:
def winged_animal_info(self):
print("Winged animals can flap.")

class Bat(Mammal, WingedAnimal):


def bat(self):
print("Bat is a winged mammal.")

# create an object of Bat class


b1 = Bat()
b1.bat()
b1.mammal_info()
b1.winged_animal_info()

Bat is a winged mammal.


Mammals can give direct birth.
Winged animals can flap.
# Performing Addition,Multiplication,Division using Multiple Inheritance

class Calculation1:
def Summation(self,a,b):
return a+b;
class Calculation2:
def Multiplication(self,a,b):
return a*b;
class Derived(Calculation1,Calculation2):
def Divide(self,a,b):
return a/b;
d = Derived()
print(d.Summation(1,2))
print(d.Multiplication(1,2))
print(d.Divide(1,2))

3
2
0.5

The issubclass(sub, sup) method:

It is used to check the relationships between the speci:ed classes. It returns true if the :rst
class is the subclass of the second class, and false otherwise.

class Calculation1:
def Summation(self,a,b):
return a+b;
class Calculation2:
def Multiplication(self,a,b):
return a*b;
class Derived(Calculation1,Calculation2):
def Divide(self,a,b):
return a/b;
d = Derived()
print(issubclass(Derived,Calculation2))
print(issubclass(Calculation1,Calculation2))

True
False

The isinstance (obj, class) method

It is used to check the relationship between the objects and classes. It returns true if the :rst
parameter, i.e., obj is the instance of the second parameter, i.e., class.
class Calculation1:
def Summation(self,a,b):
return a+b;
class Calculation2:
def Multiplication(self,a,b):
return a*b;
class Derived(Calculation1,Calculation2):
def Divide(self,a,b):
return a/b;
d = Derived()
print(isinstance(d,Derived))

True
The Diamond Problem

It refers to an ambiguity that arises when two classes Class2 and Class3 inherit from a
superclass Class1 and class Class4 inherits from both Class2 and Class3. If there is a
method “m” which is an overridden method in one of Class2 and Class3 or both then the
ambiguity arises which of the method “m” Class4 should inherit.

In the case of multiple inheritance, a given attribute is :rst searched in the current class if it’s
not found then it’s searched in the parent classes. The parent classes are searched in a left-
right fashion and each class is searched once.
# Python Program to depict multiple inheritance
# when method is overridden in both classes

class Class1:
def m(self):
print("In Class1")

class Class2(Class1):
def m(self):
print("In Class2")

class Class3(Class1):
def m(self):
print("In Class3")

class Class4(Class2, Class3):


pass

obj = Class4()
obj.m()

In Class2

When you call obj.m() (m on the instance of Class4) the output is In Class2. If Class4 is
declared as Class4(Class3, Class2) then the output of obj.m() will be In Class3.
# Python Program to depict multiple inheritance
# when method is overridden in one of the classes

class Class1:
def m(self):
print("In Class1")

class Class2(Class1):
pass

class Class3(Class1):
def m(self):
print("In Class3")

class Class4(Class2, Class3):


pass

obj = Class4()
obj.m()

In Class3
# Python Program to depict multiple inheritance
# when every class defines the same method

class Class1:
def m(self):
print("In Class1")

class Class2(Class1):
def m(self):
print("In Class2")

class Class3(Class1):
def m(self):
print("In Class3")

class Class4(Class2, Class3):


def m(self):
print("In Class4")

obj = Class4()
obj.m()

#Class2.m(obj)
#Class3.m(obj)
#Class1.m(obj)

In Class4

The output of the method obj.m() in the above code is In Class4. The method “m” of Class4
is executed. To execute the method “m” of the other classes it can be done using the class
names.
# Python Program to depict multiple inheritance
# when we try to call m of Class1 from both m of Class2 and m of Class3

class Class1:
def m(self):
print("In Class1")

class Class2(Class1):
def m(self):
print("In Class2")
Class1.m(self)

class Class3(Class1):
def m(self):
print("In Class3")
Class1.m(self)

class Class4(Class2, Class3):


def m(self):
print("In Class4")
Class2.m(self)
Class3.m(self)

obj = Class4()
obj.m()

In Class4
In Class2
In Class1
In Class3
In Class1

Super() is generally used with the init function when the instances are initialized. The super
function comes to a conclusion, on which method to call with the help of the method
resolution order (MRO). If we see the above example then the order of search for the
attributes will be Derived, Base1, Base2, object. The order that is followed is known as a
linearization of the class Derived and this order is found out using a set of rules called
Method Resolution Order (MRO). To view the MRO of a class:

Use the mro() method, it returns a list Eg. Class4.mro() Use the mro attribute, it returns a
tuple Eg. Class4.mro
# Python program to demonstrate
# super()

class Class1:
def m(self):
print("In Class1")

class Class2(Class1):
def m(self):
print("In Class2")
super().m()

class Class3(Class1):
def m(self):
print("In Class3")
super().m()

class Class4(Class2, Class3):


def m(self):
print("In Class4")
super().m()

print(Class4.mro()) #This will print list


print(Class4.__mro__) #This will print tuple
obj = Class4()
obj.m()

[<class '__main__.Class4'>, <class '__main__.Class2'>, <class '__main__.Class3


(<class '__main__.Class4'>, <class '__main__.Class2'>, <class '__main__.Class3
In Class4
In Class2
In Class3
In Class1
Data abstraction
Abstraction is used to hide the internal functionality of the function from the users. The
users only interact with the basic implementation of the function, but inner working is
hidden. User is familiar with that "what function does" but they don't know "how it does."

A class that consists of one or more abstract method is called the abstract class. Abstract
methods do not contain their implementation. Abstract class can be inherited by the
subclass and abstract method gets its de:nition in the subclass. Abstraction classes are
meant to be the blueprint of the other class. An abstract class can be useful when we are
designing large functions. An abstract class is also helpful to provide the standard interface
for different implementations of components. Python provides the abc module to use the
abstraction in the Python program.

Syntax

from abc import ABC


class ClassName(ABC):

We need to import the abc module, which provides the base for de:ning Abstract Base
classes (ABC). The ABC works by decorating methods of the base class as abstract. We use
the @abstractmethod decorator to de:ne an abstract method or if we don't provide the
de:nition to the method, it automatically becomes the abstract method.
# abstraction in python
#Abstract method has a declaration but does not have an implementation
from abc import ABC,abstractmethod
# abstract class
class Subject(ABC):
@abstractmethod
def subject(self):
print("This is a subject")

class Maths(Subject):
def subject(self):
print("Subject is Maths")

class English(Subject):
def subject(self):
print("Subject is English")

#subject=Subject()

maths=Maths()
maths.subject()

english=English()
english.subject()

Subject is Maths
Subject is English

Data Encapsulation
Encapsulation is a mechanism of wrapping the data (variables) and code acting on the data
(methods) together as a single unit. In encapsulation, the variables of a class will be hidden
from other classes, and can be accessed only through the methods of their current class.

Protected Members

Protected members are members of a class that can only be accessed within the class but
cannot be accessed by anyone outside it. This can be done in Python by following the
convention and pre:xing the name with a single underscore (_).

The protected variable can be accessed from the class and in the derived classes (it can
also be modi:ed in the derived classes), but it is customary to not access it out of the class
body.
# Python program to
# demonstrate protected members

# Creating a base class


class Base:
def __init__(self):

# Protected member
self._a = 2

# Creating a derived class


class Derived(Base):
def __init__(self):

# Calling constructor of Base class


Base.__init__(self)
print("Calling protected member of base class: ",
self._a)

# Modify the protected variable:


self._a = 3
print("Calling modified protected member outside class: ",
self._a)

obj1 = Derived()

obj2 = Base()

# Calling protected member


# Can be accessed but should not be done due to convention
print("Accessing protected member of obj1: ", obj1._a)

# Accessing the protected variable outside


print("Accessing protected member of obj2: ", obj2._a)

Calling protected member of base class: 2


Calling modified protected member outside class: 3
Accessing protected member of obj1: 3
Accessing protected member of obj2: 2
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 de:ne a private member pre:x the member name with double underscore “__”
# Python program to
# demonstrate private members

# Creating a Base class

class Base:
def __init__(self):
self.a = "HelloWorld"
self.__c = "HelloWorld"

# Creating a derived class


class Derived(Base):
def __init__(self):

# Calling constructor of
# Base class
Base.__init__(self)
print("Calling private member of base class: ")
print(self.__c)

# Driver code
obj1 = Base()
print(obj1.a)
#obj2 = Derived()
print(obj1.__c)

# Uncommenting print(obj1.c) will raise an AttributeError

# Uncommenting obj2 = Derived() will also raise an AttributeError as


# private member of base class is called inside derived class

HelloWorld
--------------------------------------------------------------------------
-
AttributeError Traceback (most recent call
last)
<ipython-input-25-cec11daf86dc> in <cell line: 27>()
25 print(obj1.a)
26 #obj2 = Derived()
---> 27 print(obj1.__c)
28
29 # Uncommenting print(obj1.c) will raise an AttributeError

AttributeError: 'Base' object has no attribute '__c'

SEARCH STACK OVERFLOW


class Student:
__schoolName = 'XYZ School' # private class attribute

def __init__(self, name, age):


self.__name=name # private instance attribute
self.__age=age # private instance attribute
def __display(self): # private method
print('This is private method.')

std = Student("Bill", 25)


print(std.__schoolName) #AttributeError
print(std.__name) #AttributeError
print(std.__display()) #AttributeError

--------------------------------------------------------------------------
-
AttributeError Traceback (most recent call
last)
<ipython-input-26-ffb8530c2345> in <cell line: 11>()
9
10 std = Student("Bill", 25)
---> 11 print(std.__schoolName) #AttributeError
12 print(std.__name) #AttributeError
13 print(std.__display()) #AttributeError

AttributeError: 'Student' object has no attribute '__schoolName'

SEARCH STACK OVERFLOW

Python performs name mangling of private variables. Every member with a double
underscore will be changed to _object._class__variable. So, it can still be accessed from
outside the class, but the practice should be refrained.

std = Student("Bill", 25)


print(std._Student__name) #'Bill'

std._Student__name = 'Steve'
print(std._Student__name) #'Steve'
std._Student__display() #'This is private method.'

Bill
Steve
This is private method.
Polymorphism
Polymorphism refers to having multiple forms. Polymorphism is a programming term that
refers to the use of the same function name, but with different signatures, for multiple types.

# Python program to demonstrate in-built polymorphic functions

# len() being used for a string


print(len("Python"))

# len() being used for a list


print(len([10, 20, 30]))

6
3

# A simple Python function to demonstrate


# Polymorphism

def add(x, y, z = 0):


return x + y+z

# Driver code
print(add(2, 3))
print(add(2, 3, 4))

5
9

Polymorphism with Inheritance


In Python, Polymorphism lets us de:ne methods in the child class that have the same name
as the methods in the parent class. In inheritance, the child class inherits the methods from
the parent class. However, it is possible to modify a method in a child class that it has
inherited from the parent class. This is particularly useful in cases where the method
inherited from the parent class doesn’t quite :t the child class. In such cases, we re-
implement the method in the child class. This process of re-implementing a method in the
child class is known as Method Overriding.
class Vehicle:
def __init__(self, brand, model):
self.brand = brand
self.model = model

def move(self):
print("Move!")

class Car(Vehicle):
pass

class Boat(Vehicle):
def move(self):
print("Sail!")

class Plane(Vehicle):
def move(self):
print("Fly!")

car1 = Car("Ford", "Mustang") #Create a Car object


boat1 = Boat("Ibiza", "Touring 20") #Create a Boat object
plane1 = Plane("Boeing", "747") #Create a Plane object

for x in (car1, boat1, plane1):


print(x.brand)
print(x.model)
x.move()

Ford
Mustang
Move!
Ibiza
Touring 20
Sail!
Boeing
747
Fly!

You might also like