0% found this document useful (0 votes)
2 views79 pages

Unit 4 Python Share

This document outlines the principles of Object-Oriented Programming (OOP) in Python, including key concepts such as classes, objects, methods, inheritance, polymorphism, abstraction, and encapsulation. It explains the significance of the __init__ method for object initialization and the differences between public, private, and protected variables. Additionally, it includes practical examples and exercises for creating classes and implementing OOP principles in Python.

Uploaded by

sanya2005sharma
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views79 pages

Unit 4 Python Share

This document outlines the principles of Object-Oriented Programming (OOP) in Python, including key concepts such as classes, objects, methods, inheritance, polymorphism, abstraction, and encapsulation. It explains the significance of the __init__ method for object initialization and the differences between public, private, and protected variables. Additionally, it includes practical examples and exercises for creating classes and implementing OOP principles in Python.

Uploaded by

sanya2005sharma
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Course: 5.

0CE202E02H: Python

UNIT 4: Object Oriented Programming

Dr. Rashima Mahajan


Professor, CSE
SET, MRIIRS Rashima Mahajan 1
Unit 4: Object Oriented Programming:

▪ Defining Classes, The Self–parameter


▪ Adding methods to a Class,
▪ Constructor and Types of constructor: The __Init__ Method,
▪ del__ Method(Destructor Method),
▪ Method Overloading in Python,
▪ Inheritance, Types of Inheritance

Rashima Mahajan 2
Object Oriented Programming

• OOP is a programming paradigm based on objects and classes.


• It helps in code reusability, modularity, and maintainability.
• Python supports OOP with features like classes, inheritance, and
polymorphism.

Rashima Mahajan 3
Object Oriented Programming
Object-Oriented Programming or OOPs refers to languages that use objects in programming. Object-
oriented programming aims to implement real-world entities like inheritance, hiding, polymorphism,
etc in programming. The main aim of OOP is to bind together the data and the functions that operate
on them so that no other part of the code can access this data except that function.

OOPs Concepts:
•Class
•Objects
•Data Abstraction
•Encapsulation
•Inheritance
•Polymorphism

Rashima Mahajan 4
OOP:
A programming paradigm based on the concept of "objects", which contain both data and methods.
OOP is designed to facilitate code reusability, scalability, and organization.
The four main principles of OOP are:
• Encapsulation: Bundling the data and methods that operate on the data within one unit (class).
• Inheritance: Creating new classes based on existing ones, allowing for code reuse and extension.
• Polymorphism: The ability to use a common interface for different underlying forms (data types).
• Abstraction: Hiding complex implementation details and showing only the essential features of the
object.
Object: An object is an instance of a class. It
encapsulates data (attributes or properties) and
Class: A blueprint or template for behavior (methods or functions) that operate on
creating objects. A class defines a the data. In OOP, everything is considered an
set of attributes (variables) and object.
methods (functions) that the Example: If Car is a class, then my_car can be
objects created from the class will an object (instance) of that class, with specific
have. attributes like color, model, and methods like
drive() or brake().
Rashima Mahajan 5
Benefits of Object-Oriented Programming
Modularity: The source code for a class can be written and maintained independently of the
source code for other classes. Once created, an object can be easily passed around inside the
system.

Reusability: Classes can be reused in different programs.

Scalability: OOP provides a clear modular structure for programs.

Extensible: The software is extensible with new features and functionality can be added easily.

Maintainable: Due to encapsulation, a change made in one part of a program does not affect
other parts.

By understanding and applying OOP principles, programmers can create applications


that are easier to write, debug, and maintain.

Rashima Mahajan 6
Defining Classes & Self-Parameter

Rashima Mahajan 7
1. Class: 2. Object:

A class is a user-defined data type. It consists of It is a basic unit of Object-Oriented Programming and

data members (variables) and member functions represents the real-life entities. An Object is an instance

(methods), which can be accessed and used by of a Class. When a class is defined, no memory is

creating an instance (object) of that class. It allocated but when it is instantiated (i.e. an object is

represents the set of properties or methods that are created) memory is allocated. An object has an identity,

common to all objects of one type. A class is like a state, and behavior. Each object contains data and code

blueprint for an object. to manipulate the data. Objects can interact without

For Example: Consider the Class of Cars. There having to know details of each other’s data or code, it is

may be many cars with different names and brands sufficient to know the type of message accepted and

but all of them will share some common properties type of response returned by the objects.

like all of them will have 4 wheels, Speed Limit, For example “Dog” is a real-life Object, which has

Mileage range, etc. So here, Car is the class, and some characteristics like color, Breed, Bark, Sleep, and

wheels, speed limits, mileage are their properties. Eats.


obj = ClassName()
class ClassName: print(obj.class_member_name)
# Statement 8
Program to access class variable using class object

class ABC:
var=10 # class variable

obj= ABC( )
print([Link]) # class variable is accessed using class object

Rashima Mahajan 9
Classes are a way of grouping together related data and functions which act upon that data. A
class is a kind of data type, just like a string, integer or list. When we create an object of that
data type, we call it an instance of a class. The data values which we store inside an object
are called attributes, and the functions which are associated with the object are called
methods.

Rashima Mahajan 10
The __init__( ) Method in Python OOP (Constructor)
The __init__ method in Python is a special instance method used for object initialization. It is also
known as the constructor because it is automatically invoked when a new object of a class is
created.

Why is it called __init__?

•The name __init__ stands for "initialize", as it is used to initialize an instance of the
class.
•It belongs to Python's dunder (double underscore) methods, also called magic
methods.
•The method runs only once per object when the object is instantiated.

Rashima Mahajan 11
The __init__( ) Method in Python OOP (Constructor)
The __init__ method in Python is a special method (also called a constructor) that is automatically
called when a new instance of a class is created. It is used to initialize object attributes.

• The __init__( ) method has a special significance in python classes. The __init__ method is called a constructor

• The __init__( ) method is automatically executed when an object of a class is created.

• This method is used to initialize the variables of the class object i.e It initializes object attributes.

• __init__( ) is prefixed as well as suffixed by double underscores.

• Note that an object is required to be created in the main module and no where the __init__( ) method is
required to be called.

• __init__() method defines the attributes that all objects will hold when they are created. This is generally
referred to as constructor in other programming languages.

Syntax: class ClassName:


def __init__(self, parameters):
Rashima Mahajan 12
# Initialize instance variables
Class Method and SELF argument
• Class methods (functions) must have the first argument named as ‘self’.
• No value is passed for this parameter when the method is called
• The ‘self’ argument refers to the object itself.
• If there is a method which takes no arguments, then also method needs to be defined to have a self argument

Create a class student and print the name and age of two students
class Student:
def __init__(self, name, age):
[Link] = name # Instance Variable
[Link] = age # Instance Variable
print("Student" , [Link], " is of age ", [Link])

# Creating an object
s1 = Student("Alice", 20)
s2 = Student("Bob", 22)

Rashima Mahajan 13
Write a Python program to create a class Car with the following specifications:
[Link] (Instance variables):
[Link] → to store the model name of the car.
[Link] → to store the color of the car.
[Link]:
1.__init__(self, model, color) → Constructor to initialize the model and color of the car.
[Link](self) → Instance method that prints a message in the format:
Lets drive <color> <model> car
[Link] Requirements:
1. Create an object car1 of the Car class with model "Tesla Model S" and color "red".
2. Print the car details using instance attributes (model and color).
3. Call the drive() method to display the driving message.

Rashima Mahajan 14
Code: • A class is defined using the class keyword followed
by the class name and a colon.
class Car:
#Initializer/Instance attributes • Inside the class, methods (functions) are defined
def __init__(self, model, color): using def, and object attributes are initialized using
[Link] = model the __init__ method.
[Link] = color
• Here, Car is a class with two attributes (model and
#instance method color) and one method (drive) print a message.
def drive(self):
print('Lets drive', [Link], [Link], 'car’)

#Instantiate the Car Class


car1 = Car("Tesla Model S", "red")

#Access the instance attributes


print('My', [Link], 'colored', 'car is of model', [Link])
#Call instance methods
[Link]() # Output: Lets drive red Tesla Model S car

Rashima Mahajan 15
Class Example (using return): • Here, Car is a class with two attributes (model and
color) and one method (drive) returns a message.
class Car:
#Initializer/Instance attributes
def __init__(self, model, color):
[Link] = model
[Link] = color

#instance method
def drive(self):
return 'Lets drive', [Link], [Link], 'car’

#Instantiate the Car Class


car1 = Car("Tesla Model S", "red")

#Access the instance attributes


print('My', [Link], 'colored', 'car is of model', [Link])
#Call instance methods
print([Link]()) # Output: Lets drive red Tesla Model S car

Rashima Mahajan 16
Class attributes vs Instance attributes
Class attributes are shared by all instances of the class, whereas instance attributes are unique to each object and
are Defined within the __init__() method.

#class vs instance attributes Output:


class Car:
wheels=4 #class attribute
#Initializer/Instance attributes
def __init__(self, model, color):
[Link] = model #instance attributes
[Link] = color

#instance method
def drive(self):
print('Lets drive', [Link], [Link], 'car with', [Link], 'wheels')
#Instantiate the Car Class
car1 = Car("Tesla Model S", "red")
car2 = Car("Honda Civic", "white")
#Access the instance attributes
print('My', [Link], 'colored', 'car is of model', [Link])
print('My', [Link], 'colored', 'car is of model', [Link])
#Call instance methods
[Link]() # Output: Lets drive red Tesla Model S car
Rashima Mahajan 17
[Link]()
SUMMARY:

Python is an object-oriented programming language. What this means is we can solve a problem in Python by
creating objects in our programs. Here, we will discuss OOPs terms such as class, objects, methods etc.
along with the Object oriented programming features such as inheritance, polymorphism, abstraction,
encapsulation.

Object
An object is an entity that has attributes and behaviour. For example, Ram is an object who has attributes such as
height, weight, color etc. and has certain behaviours such as walking, talking, eating etc.

Class
A class is a blueprint for the objects. For example, Ram, Shyam, Steve, Rick are all objects so we can define a
template (blueprint) class Human for these objects. The class can define the common attributes and behaviours of
all the objects.

Methods
As we discussed above, an object has attributes and behaviours. These behaviours are called methods in
programming.

Rashima Mahajan 18
Program to illustrate the difference between public and private variables
• In Python, class attributes class ABC:
def __init__(self, var1, var2):
and methods can be self.var1= var1
defined as public or self.__var2= var2 #Private variable

private. def display(self):


• Public variables are print('From class method, var1=', self.var1)
print('From class method, var2=', self.__var2)
accessible from outside
the class, while private obj=ABC(10, 20)
[Link]()
variables are intended print('From main module, var1=', obj.var1)
to be accessed only print('From main module, var2=', obj.__var2)

within the class.


• Private variables are
defined in the class with a
double underscore prefix
(__v)
Rashima Mahajan 19
Protected Variables in Python
In Python, protected variables are indicated by a single underscore (_) before the variable name.
These variables can still be accessed outside the class, but it's a convention that they should only be
accessed within the class or its subclasses.

Syntax of a Protected Variable


Key Points about Protected Variables in Python:
Can be accessed within the class and subclasses.
class Parent: Not strictly enforced by Python, just a naming convention
def __init__(self): Should not be accessed directly outside the class.
self._protected_var = 42 # Protected variable

def display(self):
print("Protected Variable: “, self._protected_var)

# Creating an object
obj = Parent() Output:
[Link]()
Protected Variable: 42
# Accessing the protected variable (allowed but not recommended) 42
print(obj._protected_var) # Not an error, but discouraged

Rashima Mahajan 20
Write a Python program to create a BankAccount class with the following specifications:
1. Attributes:
• account_number – Public attribute to store the account number.
• __balance – Private attribute to store the account balance.
2. Methods:
• __init__(self, account_number, balance) → Constructor to initialize account number and balance.
• deposit(self, amount) → To add money into the account (ensure deposit amount is positive).
• withdraw(self, amount) → To withdraw money if sufficient balance is available, else show “Insufficient
balance!”.
• get_balance(self) → To return the current balance.
3. Program Requirements:
• Create an object user1_account with account number "123456789" and initial balance of 1000.
• Deposit 500 and then withdraw 200.
• Display the final account balance using get_balance().
• Try to access __balance directly from the object and observe what happens.

Rashima Mahajan 21
class BankAccount:
# Constructor (Initializer)
def __init__(self, account_number, balance):
self.account_number = account_number # public attribute
self.__balance = balance # private attribute

# Deposit method
def deposit(self, amount):
self.__balance += amount

# Withdraw method
def withdraw(self, amount):
if amount <= self.__balance:
self.__balance -= amount
else:
print("Insufficient balance!")

# Get balance method


def get_balance(self):
return self.__balance
# Create an object of BankAccount
user1= BankAccount("123456789", 1000)

# Perform deposit and withdrawal


[Link](500) # Balance = 1500
[Link](200) # Balance = 1300

# Display final balance


print("Final Account Balance:", user1.get_balance())
# Try to access the private variable directly
print(user1.__balance) # This will raise an AttributeError 22
Write a Python program using Object-Oriented Programming (OOP) to:
Create a Sphere class that calculates the area and volume of a sphere.
Create a Triangle class that calculates the area of a triangle.
Use constructors to initialize values and methods to perform the calculations. Demonstrate the program by creating objects of
both classes.

# Class for Sphere


class Sphere:
def __init__(self, radius):
[Link] = radius
a= 4 * 3.14 * ([Link] ** 2)
print("Area of Sphere:", a)
v= (4/3) * 3.14 * ([Link] ** 3)
print("Volume of Sphere:", v)

# Class for Triangle


class Triangle:
def __init__(self, base, height):
[Link] = base
[Link] = height
a_triangle = 0.5 * [Link] * [Link]
print("Area of Triangle:", a_triangle)

# Sphere object
s = Sphere(5)

# Triangle object
t = Triangle(10, 6)
Rashima Mahajan 23
Problem 1: Python Programming Exercise: Implementing the Book Class
Objective: Create a Python class named Book that models the properties and actions relevant to a book in a library system.

Task Details:

[Link] Structure:
• Attributes:
• title (string): Represents the title of the book.
• author (string): Represents the author of the book.
• genre (string): Represents the genre of the book.
• page_count (integer): Represents the total number of pages in the book.
• rating (float): Represents the average reader rating out of 5.
• current_page (integer): Initially set to 1, represents the current page the reader is on.
• Methods:
• describe_book(): Prints a summary of the book, including all attributes except current_page.
• is_popular(): Returns True if the book’s rating is 4.0 or higher, otherwise returns False.
• update_page(new_page): Updates the current_page attribute to the new page number provided.
• restart_book(): Resets the current_page to 1, as if the reader is starting the book over.
[Link]:
• Create an instance of the Book class for the book titled "Harry Potter and the Sorcerer's Stone" by J.K. Rowling, classified under the
genre "Fantasy", with a total of 309 pages and a rating of 4.5.
• Print the details of the book using the describe_book() method.
• Check and print if the book is popular using the is_popular() method.
• Simulate reading by updating the current page to 150 using the update_page() method and then print the new current page.
• Restart reading the book using the restart_book() method and print the current page to verify it has been reset.

Rashima Mahajan 24
class Book:
def __init__(self,t,a,g,pc,r):
[Link]= t
[Link]=a
[Link]=g
self.page_count=pc
[Link]=r
self.current_page=1

def describe_book(self):
print("Title : ",[Link])
print("Author : ",[Link])
print("Genre : ",[Link])
print("Total Pages : ",self.page_count)
print("Rating : ",[Link])

def is_popular(self):
if [Link] > 4:
return True
else:
return False

Rashima Mahajan 25
def update_page(self,new_page):
self.current_page=new_page

def restart_book(self):
self.current_page=1

s1=Book("Harry Potter and the Sorcerer's Stone","J.K. Rowling","Fantasy",309,4.5)


s1.describe_book()
popular=s1.is_popular()
print(popular)
s1.update_page(150)
print(s1.current_page)
s1.restart_book()
print(s1.current_page)

Output:

Rashima Mahajan 26
__del__ Method (Destructor) in Python

The __del__ method is Python's destructor method, called automatically when an object is deleted or goes out of
scope. It is used to release resources, such as closing file connections or database sessions.

Syntax of __del__ Method Example 1: Basic Usage of __del__


class ClassName:
def __del__(self): class Demo:
print("Destructor called, object deleted") def __init__(self, name):
[Link] = name
print("Object ”, [Link], “ created")

def __del__(self):
print("Destructor called ”, [Link], “ deleted")

# Creating an object
obj1 = Demo("A")

Output: # Deleting the object


Object A created del obj1
Destructor called, A deleted
Rashima Mahajan 27
class Student:
def __init__(self, name):
[Link] = name
print("Student “, [Link], “admitted")

def __del__(self):
print("Destructor called student “, [Link], “removed")

s = Student("Alice")
•When s = Student("Alice") is executed, the __init__
method is called, printing "Student Alice admitted".
del s
•When the object s goes out of scope or is explicitly deleted
(del s), the __del__ method is automatically invoked,
printing "Destructor called, Student Alice removed".

Rashima Mahajan 28
Rashima Mahajan 29
Rashima Mahajan 30
Write a Python program that demonstrates the use of a constructor (__init__) to initialize a student object
and a destructor (__del__) to clean up when the object is deleted.
class Student:
def __init__(self, name, roll_no, course):
""" Constructor: Initializes the student details """
[Link] = name
self.roll_no = roll_no
[Link] = course
print("Student ", [Link], " Roll No: ", self.roll_no, " admitted to ", [Link])
def display_details(self):
""" Method to display student details """
print("Student Name: ", [Link], ", Roll No: ", self.roll_no, ", Course: ", [Link])
def __del__(self):
""" Destructor: Called when the object is deleted """
print("Student ", [Link], " Roll No: ", self.roll_no, " record removed.")
# Creating a Student object
s1 = Student("Alice", "S101", "Computer Science")
s1.display_details() # Using the object
del s1 Rashima
# Deleting theMahajan
object manually 31
Rashima Mahajan 32
Fundamental Features of Object-Oriented Programming:

• Encapsulation: Encapsulation refers to the bundling of data and methods


within a class, hiding the internal details and providing a public interface to
interact with the object.
• Inheritance: Inheritance allows classes to inherit attributes and methods
from a parent class. It promotes code reuse and supports hierarchical
relationships between classes.
• Polymorphism: Polymorphism allows objects of different classes to be
treated as objects of a common superclass. It enables the use of a single
interface to represent multiple types of objects.

Rashima Mahajan 33
Encapsulation:
• Encapsulation is the process of bundling data and related methods (functions) into a single unit
called a class. It hides the internal implementation details and provides a public interface for
interacting with the object.

• It restricts access to some of the object's components, which is a way of protecting the data
from unauthorized access and modification. This is often achieved using private variables and
methods.

• Key Purpose: Data hiding and protection by restricting access to certain components using
access specifiers (like private or protected).

Rashima Mahajan 34
Ques: Demonstrate encapsulation by class BankAccount:
making variables private. Create a def __init__(self, account_number, balance):
class - BankAccount with attributes self.account_number = account_number
account number and balance, self.__balance = balance
deposit 2000 INR in the account and
print the balance, withdraw amount def deposit(self, amount):
and print the balance. self.__balance += amount
In this example, encapsulation of the def withdraw(self, amount):
attributes has been done by using
if amount <= self.__balance:
private variables (denoted by double
self.__balance -= amount
underscores __).
else:
Here, __balance is encapsulated
(private) attribute and cannot be
print("Insufficient balance!")
accessed directly from outside the
class. def get_balance(self):
Instead, getter method get_balance() return self.__balance
has been used to access the private
data. # Creating an object of the BankAccount class
This ensures data protection, hiding user1_account = BankAccount("123456789", 1000)
sensitive details from external access.
user1_account.deposit(500)
user1_account.withdraw(200)
Output: print("Account Balance:", user1_account.get_balance())
print(user1_account.__balance) # Not Allowed (Private
variable) Rashima Mahajan 35
In this example, the BankAccount class encapsulates the account number
and balance attributes, as well as methods for depositing,
withdrawing, and getting the balance. The internal data (account_number
and balance) are hidden from external access, and interactions with the
object are performed through the public methods.

Rashima Mahajan 36
Another example of Encapsulation: Print the attributes of Class Car (Brand, Model as private variables and fuel capacity as
public) to demonstrate the concept of encapsulation

class Car:
def __init__(self, brand, model, fuel_capacity):
self.__brand = brand # Encapsulated (private) variable
self.__model = model # Encapsulated (private) variable
self.fuel_capacity = fuel_capacity # Public variable

def display_info(self):
print("Brand:”, self.__brand, “Model: “, self.__model)

# accessing the private attribute


def get_brand(self):
return self.__brand

# modifying the private attribute


def set_brand(self, brand):
self.__brand = brand

Rashima Mahajan 37
# Using the class
my_car = Car("Toyota", "Corolla", 50)
my_car.display_info()

# Trying to access private variables directly (will fail)


# print(my_car.__brand) # This will raise an AttributeError

# Accessing private variable using class method (function)


print("Brand (using getter):", my_car.get_brand())

# Modifying private variable using class method


my_car.set_brand("Honda")
my_car.display_info()

Rashima Mahajan 38
Explanation (Encapsulation):
• Here, __brand and __model are encapsulated (private) attributes and cannot be
accessed directly from outside the class.
• Instead, used methods (get_brand() and set_brand()) to access and modify the private
data.
• This ensures data protection, hiding sensitive details from external access.

Rashima Mahajan 39
Inheritance:
✓ Inheritance is a mechanism that allows a class (child/subclass) to inherit
properties and methods from another class (parent/superclass).
✓ It promotes code reuse, extensibility, and the creation of hierarchical
relationships between classes.
✓ Inheritance allows user to create a new class that is a modified version of
an existing class.
✓ The new class inherits attributes and methods from the parent class,
allowing for code reuse and the creation of a class hierarchy.

Inheritance is a mechanism where a new class derives attributes and methods from an existing class.
The class from which attributes and methods are inherited is called the base class, parent class, or
superclass. The class that inherits those members is called the derived class, child class, or subclass.

Rashima Mahajan 40
Rashima Mahajan 41
Write a Python program to demonstrate the concept of inheritance using the following specifications:

[Link] a base class Vehicle with:


1. Attributes: brand, model
2. Method: display_info() → Prints the brand and model of the vehicle.
[Link] a derived class Car that inherits from Vehicle with:
1. Additional attribute: car_type
2. Overridden method: display_info() → First call the base class method, then display the car
type.
[Link] Requirements:
1. Create an object car of the Car class with brand "Toyota", model "Corolla", and type
"Sedan".
2. Call the display_info() method to display all the details.

Rashima Mahajan 42
class Vehicle: # Base class
def __init__(self, brand, model):
[Link] = brand
[Link] = model

def display_info(self):
print('Brand :', [Link])
print('Model :', [Link])

class Car(Vehicle): # Derived class


def __init__(self, brand, model, car_type):
Vehicle.__init__(self, brand, model) #importing base class
self.car_type = car_type

def display_info(self):
Vehicle.display_info(self) #importing base class method
print('Car Type:', self.car_type)
OUTPUT:
# Using the derived class
car = Car("Toyota", "Corolla", "Sedan")
car.display_info()

Rashima Mahajan 43
#Using super() method.....omit self while using super()
class Vehicle: # Base class
def __init__(self, brand, model):
[Link] = brand
[Link] = model

def display_info(self):
print('Brand :', [Link])
print('Model :', [Link])

class Car(Vehicle): # Derived class


def __init__(self, brand, model, car_type):
super().__init__(brand, model)
self.car_type = car_type

def display_info(self):
super().display_info()
print('Car Type:', self.car_type)

# Using the derived class


car = Car("Toyota", "Corolla", "Sedan")
car.display_info()
Rashima Mahajan 44
✓ The super() method in Python is class Parent:
used in the context of inheritance to def __init__(self, name):
allow a child (or subclass) to access [Link] = name
methods or attributes of its parent (or print("Parent constructor called for “, [Link])
superclass)
class Child(Parent):
✓ Using super() helps in writing clean def __init__(self, name, age):
code by eliminating the need to super().__init__(name) # Calls Parent's
explicitly refer to the parent class by constructor without explicitly passing self
name. This is useful especially when [Link] = age
dealing with multiple inheritance print("Child constructor called for “, [Link],
(where there are more than one parent “Age: “, [Link])
classes).
# Creating an object
✓ During Method Overriding: c = Child("Alice", 25)
When one overrides a method in a
child class but still want to retain the Output:
functionality of the parent class's Parent constructor called for Alice
method. Using super() allows user to Child constructor called for Alice, Age: 25
call the parent class's method in
addition to adding new functionality.
Rashima Mahajan 45
✓ To Initialize the class Animal:
def __init__(self, name):
Parent Class:When
[Link] = name
the child class's print("Animal “, [Link], “ is created.")
__init__() method
needs to call the class Dog(Animal):
def __init__(self, name, breed):
__init__() method
super().__init__(name) # Initialize the Animal class
of the parent class [Link] = breed
to properly initialize print("Dog breed is “, [Link])
the parent’s
dog = Dog("Buddy", "Golden Retriever")
attributes.

OUTPUT:
Animal Buddy is created.
Dog breed is Golden Retriever

Rashima Mahajan 46
Demonstration of Inheritance: Python class hierarchy involving a base class Person (name and age) and
derived classes Student (branch and marks) and Teacher (experience and research area).
class Person:
def __init__(self, name, age):
[Link]=name
[Link]=age

def display(self):
print('NAME:', [Link])
print('AGE:', [Link])

class Teacher(Person):
def __init__(self, name, age, experience, research_area):
super().__init__(name, age)
[Link]=experience
self.research_area=research_area

def display(self):
super().display()
print('EXPERIENCE:', [Link])
print('RESEARCH_AREA:', self.research_area)

Rashima Mahajan 47
class Student(Person):
def __init__(self, name, age, branch, marks):
super().__init__(name, age)
[Link]=branch
[Link]=marks

def display(self):
super().display()
print('BRANCH:', [Link])
print('MARKS:', [Link])

print('***************TEACHER********************')
T1=Teacher('Jaya', 30, 15, 'Machine Learning')
[Link]()

print('*************STUDENT********************')
S1=Student('Nisha', 19, 'CSE', 'SGPA 9')
[Link]()

Rashima Mahajan 48
Design a class Grandparent with an attribute family_name. Derive Parent from Grandparent and Child from
Parent, ensuring the child can access the grandparent’s attribute.

class Grandparent:
def __init__(self, family_name):
self.family_name = family_name

class Parent(Grandparent):
def __init__(self, family_name, parent_name):
super().__init__(family_name)
self.parent_name = parent_name

class Child(Parent):
def __init__(self, family_name, parent_name, child_name):
super().__init__(family_name, parent_name)
self.child_name = child_name
def display_family_info(self):
print("Family Name: ",self.family_name)
print("Parent Name: ", self.parent_name)
print("Child Name: ", self.child_name)

# Example Usage
child_obj = Child("Smith", "John", "Emma") Output:
child_obj.display_family_info()

Rashima Mahajan 49
Polymorphism:

✓ Polymorphism allows objects of different classes to be treated as objects of a common superclass. It


enables the use of a single interface to represent multiple types of objects.

✓ Polymorphism is one of the fundamental concepts in Object-Oriented Programming (OOP). It refers to the
ability of different classes to be treated as instances of the same class through a common interface.
Essentially, polymorphism allows the same method or operation to behave differently depending on the
object that calls it.

✓ Run-time polymorphism (Method Overriding): This is the most common type of polymorphism in
Python and occurs when a method in a subclass has the same name as a method in its parent
class but behaves differently.

•Key Idea: The same function or method can be used with different types of objects, and each object can
respond in its own way.

Rashima Mahajan 50
The previous example of Python class hierarchy involving a base class Person and derived classes
Student and Teacher also demonstrates the concept of polymorphism

Polymorphism refers to the ability of different classes to define methods with the same name, and
for Python to automatically call the appropriate method based on the object's class.

In this example, both the Teacher and Student classes inherit from the Person class. Each of
these classes has its own version of the display() method, which is overridden from the Person
class.

Method Overriding: The Person class has a display() method that prints the name and age of a
person. The Teacher and Student classes both override the display() method to add more specific
information (e.g., experience and research_area for Teacher; branch and marks for Student).

Polymorphism is demonstrated because the same display() method name is used in


different classes (Person, Teacher, Student), but the behavior of the method depends on the class
of the object calling it.

Rashima Mahajan 51
PROBLEM 2
Design a Python script that demonstrates polymorphism through inheritance, by
creating a base class Shape and two derived classes Circle and Rectangle.
Implement the following:
✓ The Shape class should have a constructor that initializes a color attribute and
a method display_info() to print the color.
✓ The Circle class should inherit from Shape, initialize the color and radius, and
override the display_info() method to print the color and radius.
✓ The Rectangle class should inherit from Shape, initialize the color, length, and
width, and override the display_info() method to print the color and dimensions.
✓ Demonstrate polymorphism by creating a list of Shape objects that include both
Circle and Rectangle, and call the display_info() method for each object in the list.
Rashima Mahajan 52
class Shape:
def __init__(self, color):
[Link] = color

def display_info(self):
print("Shape color:”, [Link])

class Circle(Shape):
def __init__(self, color, radius):
super().__init__(color) # Calling the base class
[Link] = radius

def display_info(self):
super().display_info()
print("Circle radius: “, [Link])

Rashima Mahajan 53
class Rectangle(Shape):
def __init__(self, color, length, width):
super().__init__(color) # Calling the base class constructor
[Link] = length
[Link] = width

def display_info(self):
super().display_info()
print("Rectangle dimensions: “, [Link] x [Link])

# Demonstrating polymorphism with __init__()


shapes = [Circle("Red", 5), Rectangle("Blue", 10, 4)] #objects

for shape in shapes:


shape.display_info()
print() # Empty line for better readability

Rashima Mahajan 54
Rashima Mahajan 55
Rashima Mahajan 56
Create a base class Animal with a method make_sound(). Derive a class Dog that overrides the method to print "Bark" and
a class Cat that overrides the method to print “Meow”. Demonstrate The concept of method (function ) overriding.

class Animal:
def make_sound(self):
print("Some generic animal sound")
class Dog(Animal):
def make_sound(self):
print("Bark")
class Cat(Animal):
def make_sound(self):
print("Meow")
# Example Usage
animal = Animal()
animal.make_sound() # Outputs: Some generic animal sound
dog = Dog()
dog.make_sound() # Outputs: Bark
cat = Cat()
cat.make_sound() # Outputs: Meow Output:

Rashima Mahajan 57
Write a Python script to simulate a basic ATM machine where a user can check balance, deposit money, withdraw money
(with sufficient balance check), and exit.
Example: Input: Withdraw 3000(Balance = 2000)
Output: Insufficient balance!
class ATM:
def __init__(self, balance=0):
[Link] = balance
def check_balance(self):
print(f"Your current balance is: ${[Link]}")
def deposit(self, amount):
if amount > 0:
[Link] += amount
print(f"${amount} deposited successfully.")
else:
print("Invalid deposit amount!")
def withdraw(self, amount):
if amount > [Link]:
print("Insufficient balance!")
elif amount <= 0:
print("Invalid withdrawal amount!")
else:
[Link] -= amount
print(f"${amount} withdrawn successfully.")

Rashima Mahajan 58
def run(self):
while True:
print("\nATM Menu:")
print("1. Check Balance")
print("2. Deposit Money")
print("3. Withdraw Money")
print("4. Exit")
choice = input("Choose an option (1-4): ")
if choice == '1':
self.check_balance()
elif choice == '2':
amount = float(input("Enter deposit amount: "))
[Link](amount)
elif choice == '3':
amount = float(input("Enter withdrawal amount: "))
[Link](amount)
elif choice == '4':
print("Thank you for using the ATM. Goodbye!")
break
else:
print("Invalid choice! Please select a valid option.")
# Initialize ATM with a balance of $2000
atm = ATM(balance=2000)
[Link]()
Output:

Rashima Mahajan 59
Project-PROBLEM
[Link]:
1. Make a class called Restaurant.
2. The __init__() method for Restaurant should store two attributes: a restaurant_name and a cuisine_type.
3. Make a method called describe_restaurant() that prints these two pieces of information, and a method called open_restaurant() that
prints a message indicating that the restaurant is open.
4. Make an instance called restaurant from your class. Print the two attributes individually, and then call both methods.
[Link] Restaurants:
1. Start with your class from Exercise 1. Create three different instances from the class, and call describe_restaurant() for each instance
[Link] Served:
1. Start with your program from Exercise 1.
2. Add an attribute called number_served with a default value of 0.
3. Create an instance called restaurant from this class. Print the number of customers the restaurant has served, and then change this
value and print it again.
4. Add a method called set_number_served() that lets you set the number of customers that have been served. Call this method with a
new number and print the value again.
5. Add a method called increment_number_served() that lets you increment the number of customers who’ve been served. Call this
method with any number you like that could represent how many customers were served in, say, a day of business.
[Link]:
1. Make a class called User.
2. Create two attributes called first_name and last_name, and then create several other attributes that are typically stored in a user profile.
3. Make a method called describe_user() that prints a summary of the user’s information.
4. Make another method called greet_user() that prints a personalized greeting to the user.
5. Create several instances representing different users, and call both methods for each user.
6. Login Attempts: Add an attribute called login_attempts to your User class.
7. Write a method called increment_login_attempts() that increments the value of login_attempts by 1.
8. Write another method called reset_login_attempts() that resets the value of login_attempts to 0.
9. Make an instance of the User class and call increment_login_attempts() several times.
10. Print the value of login_attempts to make sure it was incremented properly, and then call reset_login_attempts().
11. Print login_attempts again to make sure it was reset to [Link] Mahajan 60
Method Overloading in Python

Method Overloading refers to the ability to define multiple methods with the same name but different parameters in
a programming language. It allows a function to behave differently based on the number or type of arguments passed.

Unlike languages such as Java or C++, Python does not support method overloading natively. In Python, if we define
multiple methods with the same name in a class, the latest definition will override the previous ones.

Instead, Python achieves overloading through default arguments or variable arguments.

class Example:
def display(self, a):
print("Method with one argument: ", a)
def display(self, a, b):
print("Method with two arguments: ", a, b)

obj = Example()
# [Link](10) # Error: Python does not support traditional method overloading
[Link](10, 20) # Works because the second method overrides the first one

Output:
Rashima Mahajan 61
Rashima Mahajan 62
Create a class- Product and demonstrate the concept of method overloading with 2 and 3 arguments.

Rashima Mahajan 63
Create a Class-example , define a function add, first with 2 arguments and then with 3 arguments. Demonstrate
the concept Of method overloading.
The first call to add() method with three
arguments is successful. However, calling
add() method with two arguments as
defined in the class fails as Python
considers only the latest definition of the
add( ) method, discarding the earlier
definitions.

Rashima Mahajan 64
Create a Class- Calculator with two methods named – add and explain the concept of method overloading.

class Calculator:
def add(self, a):
print("Sum with one argument:", a)

def add(self, a, b):


print("Sum with two arguments: ", a + b)

# Creating an object of Calculator


calc = Calculator()

# [Link](10) # Uncommenting this will cause an error


[Link](10, 20) # Works because the second method overrides the first one

Rashima Mahajan 65
Rashima Mahajan 66
The error occurs because Python does not support traditional method overloading like some other
languages (e.g., Java, C++). In Calculator class, we have defined two add methods: one that takes
one argument and another that takes two arguments. However, Python does not choose between
these methods based on the number of arguments provided during the call. Instead, the second
definition of the add method overrides the first definition.

When we call [Link](10), Python tries to execute the add method that expects two arguments
(a and b). Since we are only providing one argument (10), it raises a TypeError indicating that the
required argument 'b' is missing.

Rashima Mahajan 67
Suggested Changes:
1. Overloading with Default Arguments
2. Overloading with variable Arguments

[Link] with default arguments


class Calculator:
def add(self, a, b=None): # Adding a default value for 'b’
if b is None:
print("Sum with one argument:", a)
else:
print("Sum with two arguments: ", a + b)
# Creating an object of Calculator
calc = Calculator()
[Link](10) # Now this will work
[Link](10, 20) # This will also work

Rashima Mahajan 68
Explanation of Changes:

[Link] Value for b: We modify the add method to accept an optional


second argument b with a default value of None. This allows the
method to handle both cases: when one or two arguments are
provided.

[Link] Logic: Inside the add method, we check if b is None. If it is,


it means only one argument was provided, and we execute the logic for
a single argument. Otherwise, we proceed with the logic for two
arguments.

Rashima Mahajan 69
Create a class example with function (method) add having 3 default arguments to show the concept of method overloading

Rashima Mahajan 70
2. Overloading with Variable Arguments (*args)
The *args parameter allows passing a variable number of positional arguments to a function.

class Calculator:

def add(self, *args):

return sum(args)

calc = Calculator()

print([Link](10)) # 10

print([Link](10, 20)) # 30

print([Link](10, 20, 30)) # 60

Rashima Mahajan 71
Combining *args and **kwargs (variable keyword args) for Flexibility

class Example:
def display(self, *args, **kwargs):
print("Positional Arguments:", args)
print("Keyword Arguments:", kwargs)

obj = Example()
[Link](10, 20, name="Alice", age=25)

Rashima Mahajan 72
Implement Method Overloading Using MultipleDispatch

• Python's standard library doesn't have any other provision for


implementing method overloading. However, we can use a
dispatch function from a third-party module
named MultipleDispatch for this purpose.
• First, you need to install the Multipledispatch module using the
following command −

Rashima Mahajan 73
from multipledispatch import dispatch
This module has
a @dispatch decorator. class Calculator:

It takes the number of @dispatch(int, int)


arguments to be passed def add(self, a, b):
return a + b
to the method to be
overloaded. Define @dispatch(float, float)
def add(self, a, b):
multiple copies of add() return a + b
method with
@dispatch(int, int, int)
@dispatch decorator as def add(self, a, b, c):
below − return a + b + c

calc = Calculator()

print([Link](10, 20)) # Calls int, int -> Output: 30


print([Link](5.5, 2.3)) # Calls float, float -> Output: 7.8
print([Link](1, 2, 3)) # Calls int, int, int -> Output: 6
Rashima Mahajan 74
Handling Mixed Data Types
You can define methods for different type combinations:

@dispatch(int, float)
def add(a, b):
return a + b

@dispatch(float, int)
def add(a, b):
return a + b

print(add(5, 2.5)) # Output: 7.5


print(add(3.2, 2)) # Output: 5.2

Rashima Mahajan 75
Sample Question Bank
1. Describe how encapsulation works and why it is important in object-oriented design.
2. Explain the difference between procedural programming and object-oriented programming with examples.
Create a program that calculates the grade of a student based on their scores.
3. Evaluate the effectiveness of polymorphism in reducing code duplication. Provide an example where
polymorphism improves the flexibility of the code.
4. Analyze how inheritance allows code reuse in object-oriented programming. Illustrate this by creating a
Python class hierarchy involving a base class Person and derived classes Student and Teacher.
5. Write a Python program that defines multiple classes and demonstrates inheritance by creating subclasses
that inherit and extend the properties.
6. Design a Python script that demonstrates polymorphism through inheritance, by creating a base class Shape
and two derived classes Circle and Rectangle. Implement the following:
• The Shape class should have a constructor that initializes a color attribute and a method display_info()
to print the color.
• The Circle class should inherit from Shape, initialize the color and radius, and override the display_info()
method to print the color and radius.
• The Rectangle class should inherit from Shape, initialize the color, length, and width, and override the
display_info() method to print the color and dimensions.
• Demonstrate polymorphism by creating a list of Shape objects that include both Circle and Rectangle,
and call the display_info() method for each object in the list.
7. Illustrate the concept of encapsulation using example.
Rashima Mahajan 76
Remembering level questions:
18. What is polymorphism in Object-Oriented Programming? Provide examples of two different forms of
polymorphism in Python.
19. State the difference between a class and an object. Provide examples.
20. How do you call a parent class constructor from a child class in Python?
Understanding:
21. Illustrate how inheritance can be used to extend the functionality of a base class in Python. Provide
code examples to support your explanation.
Applying:
22. Create a Python class Employee with attributes name, position, and salary. Use inheritance to define
a subclass Manager that has an additional attribute department. Write methods to compute the total salary
for employees in a department.

Rashima Mahajan 77
Analyzing:
23. Differentiate between encapsulation and polymorphism. Analyze how these two concepts can be applied
together in a Python program.

Evaluating:
24. Assess the advantages of using inheritance and encapsulation in a large-scale object-oriented software
project. Evaluate scenarios where they may introduce complexity or potential problems.

Creating:
25. Design a Python program that implements a class hierarchy for geometric shapes, including classes for
Circle, Rectangle, and Triangle. Use inheritance and polymorphism to compute area and perimeter for each
shape. Ensure that you encapsulate data appropriately.
25. Create two base classes, Bird with a method fly() and Mammal with a method walk(). Derive a class
Bat that inherits from both and can perform both actions.

26. Implement a class Calculator with a method add() that can take either two or three numbers as
arguments and return their sum. – Method Overloading
Rashima Mahajan 78
class Bird:
def fly(self):
print("I can fly")
class Mammal:
def walk(self):
print("I can walk")
class Bat(Bird, Mammal):
pass
# Example Usage
bat = Bat()
[Link]() # Outputs: I can fly
[Link]() # Outputs: I can walk

Rashima Mahajan 79

You might also like