ALARD UNIVERSITY
Subject: Computer Programming-I
Unit IV
Chapter 4: Object-Oriented Programming in
Python
Object-Oriented Programming (OOP) is a programming
approach based on the concept of objects, which can contain
data and code: data in the form of attributes (variables) and
code in the form of methods (functions). OOP makes it easier to
structure code, reuse it, and create complex systems.
Python fully supports OOP with several essential features that
we’ll explore in detail in this chapter:
1. Classes: Blueprints that define attributes and methods for
creating objects.
2. Objects: Instances created from a class that hold unique
data and can perform actions.
3. Methods: Functions inside classes that define behaviors or
actions objects can perform.
4. Message Passing: Calling methods on objects to perform
actions.
5. Inheritance: Mechanism to create new classes from
existing classes to reuse and extend functionality.
6. Polymorphism: Allows objects of different classes to be
treated as instances of the same class through method
overriding.
7. Containership (Composition): A design where a class
contains another class as part of its structure.
8. Reusability: Using inheritance and composition, we can
create reusable classes and methods.
9. Delegation: An object can delegate a task to an associated
object rather than performing it directly.
10. Data Abstraction: Hiding complex details and exposing
only the essentials.
11.Encapsulation: Bundling data and methods and controlling
access to protect the object's internal state.
By: Prof. Ganesh S. Wayal
ALARD UNIVERSITY
4.1 Classes
What is a Class?
A class is like a blueprint for creating objects. Think of a class as
a recipe or a template. When you design something, you usually
start with a blueprint. In programming, a class serves the same
purpose—it defines the structure (attributes) and behavior
(methods) that objects created from that class will have.
Key Terms:
● Attributes: Variables that hold data about the object.
● Methods: Functions inside the class that define the
behavior of the object.
Syntax:
To create a class in Python, use the class keyword:
class ClassName:
# Attributes and methods defined here
pass
Example:
Let’s create a simple Car class to understand how classes work.
class Car:
# The initializer method is called when we
create a new object
def __init__(self, make, model, year):
# Initializing the attributes
self.make = make # Car's brand,
like Toyota or Ford
self.model = model # Model of the
car, like Corolla or Mustang
By: Prof. Ganesh S. Wayal
ALARD UNIVERSITY
self.year = year # Year the
car was manufactured
# A method to display the car's
information
def display_info(self):
print(f"{self.year} {self.make}
{self.model}")
Explanation:
● class Car:: This defines a new class called Car.
● __init__ Method: This special method, also called a
constructor, initializes the object’s attributes when an
object is created.
○ self is a reference to the current object, allowing
the class to store data specific to that object.
● Attributes: self.make, self.model, and self.year
are attributes, storing data specific to each car object.
● Method display_info: This method is defined to
display the car’s information.
4.2 Objects
What is an Object?
An object is an instance of a class. If a class is a blueprint, then
an object is the actual product created from that blueprint. Each
object has its own set of data and can use the methods defined by
the class.
How to Create an Object:
To create an object, use the class name followed by parentheses,
passing any required arguments.
my_car = Car("Toyota", "Corolla", 2020)
By: Prof. Ganesh S. Wayal
ALARD UNIVERSITY
Example:
Using the Car class we created, let’s make an object and interact
with it.
# Creating an object (instance) of the Car
class
my_car = Car("Toyota", "Corolla", 2020)
# Using the display_info method on the my_car
object
my_car.display_info() # Output: 2020 Toyota
Corolla
Explanation:
● my_car = Car("Toyota", "Corolla", 2020):
Here, we create an object my_car from the Car class. This
object has its own make, model, and year values.
● Calling display_info(): By calling this method on
my_car, we get the car’s information displayed.
4.3 Methods
What is a Method?
A method is a function that is defined within a class. It defines
actions that the object can perform. Think of methods as the
abilities of an object. They use the data stored in the object to
perform operations or return information.
Types of Methods:
1. Instance Methods: Work with an object’s attributes.
2. Class Methods: Operate on class-level data.
By: Prof. Ganesh S. Wayal
ALARD UNIVERSITY
3. Static Methods: General functions within a class
but not specific to an object.
We’ll focus on instance methods here.
Example of Adding More Methods:
Let’s add another method to the Car class to honk the horn.
class Car:
def __init__(self, make, model, year):
self.make = make
self.model = model
self.year = year
def display_info(self):
print(f"{self.year} {self.make}
{self.model}")
def honk(self):
print("Beep beep!") # A new method
for honking the horn
# Creating an object and using its methods
my_car = Car("Toyota", "Corolla", 2020)
my_car.display_info() # Output: 2020 Toyota
Corolla
my_car.honk() # Output: Beep beep!
Explanation:
● honk Method: We added a new method honk, which
simply prints "Beep beep!" to simulate the car honking.
● Calling Methods: We call my_car.display_info()
and my_car.honk() to make the car object display its
information and honk.
By: Prof. Ganesh S. Wayal
ALARD UNIVERSITY
Keywords:
● Method: A function within a class, like
display_info and honk in this example.
● self: Refers to the current object (instance) of the class. It
allows the method to access and modify the object’s
attributes.
4.4 Message Passing
What is Message Passing?
Message passing refers to the process of calling methods on an
object to make it perform actions. In OOP, objects communicate
by sending messages (calling methods) to each other.
Example of Message Passing:
When we call my_car.display_info(), we’re sending a
message to the my_car object to display its information.
Similarly, calling my_car.honk() is a message to my_car to
perform the honking action.
# Message passing example
my_car.display_info() # Sending a message to
my_car to display info
my_car.honk() # Sending a message to
my_car to honk
Explanation:
● When we call a method on an object (e.g.,
my_car.display_info()), it’s like sending a message
to that object to take action.
Practical Example:
By: Prof. Ganesh S. Wayal
ALARD UNIVERSITY
Consider a Phone class where each phone can make
calls, send texts, and display its details. Each method call
is a form of message passing.
class Phone:
def __init__(self, brand, model):
self.brand = brand
self.model = model
def make_call(self, number):
print(f"Calling {number}...")
def send_text(self, number, message):
print(f"Sending text to {number}:
{message}")
def display_details(self):
print(f"Phone: {self.brand}
{self.model}")
# Creating a Phone object
my_phone = Phone("Apple", "iPhone 14")
# Message passing: calling methods on the
object
my_phone.display_details() # Output:
Phone: Apple iPhone 14
my_phone.make_call("123-456-7890") # Output:
Calling 123-456-7890...
my_phone.send_text("123-456-7890", "Hello!")
# Output: Sending text to 123-456-7890: Hello!
Keywords:
By: Prof. Ganesh S. Wayal
ALARD UNIVERSITY
● Message Passing: The process of calling methods on an
object, like make_call and send_text.
4.5 Inheritance
What is Inheritance?
Inheritance is an OOP feature that allows a class (child class) to
inherit attributes and methods from another class (parent class).
This helps reuse existing code and build upon it without
rewriting everything.
Key Terms:
● Parent (or Base) Class: The class whose attributes and
methods are inherited by another class.
● Child (or Derived) Class: The class that inherits from the
parent class.
Example:
Let’s create a Vehicle class and a Car class that inherits from
it.
class Vehicle:
def __init__(self, make, model):
self.make = make
self.model = model
def display_info(self):
print(f"Vehicle: {self.make}
{self.model}")
# Car class inherits from Vehicle
class Car(Vehicle):
def __init__(self, make, model, year):
By: Prof. Ganesh S. Wayal
ALARD UNIVERSITY
super().__init__(make, model) # Calls the
parent class's __init__ method
self.year = year
def display_info(self):
super().display_info() # Calls the
parent class's display_info method
print(f"Year: {self.year}")
# Creating an object of Car
my_car = Car("Toyota", "Corolla", 2020)
my_car.display_info()
Explanation:
● class Car(Vehicle):: The Car class inherits from
the Vehicle class, gaining its attributes and methods.
● super(): A keyword used to call a method from the
parent class. We use super().__init__ to initialize the
parent class attributes.
● The display_info method in the Car class also calls the
display_info method from Vehicle using super()
to show how we can extend a parent class's functionality in
a child class.
4.6 Polymorphism
What is Polymorphism?
Polymorphism allows objects of different classes to be treated as
objects of a common superclass. It means “many forms” and lets
us define methods in different ways depending on the object.
By: Prof. Ganesh S. Wayal
ALARD UNIVERSITY
Example of Method Overriding:
Method overriding is a type of polymorphism. It allows a
child class to provide a specific implementation of a method
already defined in its parent class.
class Animal:
def sound(self):
print("Animal makes a sound")
class Dog(Animal):
def sound(self):
print("Dog barks")
class Cat(Animal):
def sound(self):
print("Cat meows")
# Creating objects of Dog and Cat
my_dog = Dog()
my_cat = Cat()
# Polymorphism in action
my_dog.sound() # Output: Dog barks
my_cat.sound() # Output: Cat meows
Explanation:
● Method Overriding: Both Dog and Cat classes override
the sound method from the Animal class. When we call
sound, the specific version for each subclass runs.
Practical Use of Polymorphism:
This makes code more flexible and easy to extend, as we can add
new classes without changing the parent structure.
By: Prof. Ganesh S. Wayal
ALARD UNIVERSITY
4.7 Containership (Composition)
What is Containership (Composition)?
Containership (or Composition) is a design where a class
contains another class as a part of its attributes. It represents a
“has-a” relationship rather than an “is-a” relationship.
Example:
Let’s create a Car class that has an Engine class as one of its
attributes.
class Engine:
def start(self):
print("Engine started")
class Car:
def __init__(self, make, model, engine):
self.make = make
self.model = model
self.engine = engine # Car contains
an Engine
def start_car(self):
print(f"Starting {self.make}
{self.model}")
self.engine.start() # Delegates
starting to the Engine
# Creating an Engine object
my_engine = Engine()
# Creating a Car object with an Engine
my_car = Car("Toyota", "Corolla", my_engine)
my_car.start_car()
By: Prof. Ganesh S. Wayal
ALARD UNIVERSITY
Explanation:
● Composition: The Car class has an instance of the
Engine class. This shows a "has-a" relationship, where a
car “has an” engine.
4.8 Reusability
What is Reusability?
Reusability is a core benefit of OOP that allows classes, methods,
and objects to be reused across different parts of a program.
Using inheritance, composition, and modular classes, we can
avoid duplicating code.
Example:
Using inheritance, the Car class inherited attributes and
methods from the Vehicle class, which demonstrates
reusability. Similarly, methods defined in a class can be reused
by all objects created from that class.
Benefits:
Reusability saves development time, reduces errors, and makes
it easier to maintain code since each reusable piece is defined
once.
4.9 Delegation
What is Delegation?
Delegation is when an object passes a responsibility to another
object. It means that instead of implementing functionality
directly, an object can "delegate" a task to an associated object.
Example of Delegation:
By: Prof. Ganesh S. Wayal
ALARD UNIVERSITY
In the example above, the Car class delegates the task of
starting to its Engine class by calling
self.engine.start().
4.10 Data Abstraction
What is Data Abstraction?
Data abstraction is the process of hiding unnecessary details and
exposing only essential information to the user. This makes the
system easier to use and prevents users from seeing complex
internal details.
Example:
Let’s add some private attributes to a BankAccount class to
hide details.
class BankAccount:
def __init__(self, balance):
self.__balance = balance # Private
attribute
def deposit(self, amount):
self.__balance += amount
def withdraw(self, amount):
if amount <= self.__balance:
self.__balance -= amount
return amount
else:
print("Insufficient funds")
def get_balance(self):
return self.__balance
By: Prof. Ganesh S. Wayal
ALARD UNIVERSITY
# Creating a BankAccount object
account = BankAccount(1000)
account.deposit(500)
print("Balance:", account.get_balance()) #
Output: Balance: 1500
Explanation:
● Private Attributes: The __balance attribute is private
(indicated by the double underscores __). It cannot be
accessed directly from outside the class.
● Data Abstraction: By providing a get_balance method,
we expose only the necessary detail, hiding the complexity
of balance manipulation.
4.11 Encapsulation
What is Encapsulation?
Encapsulation is the concept of bundling data (attributes) and
methods (functions) within a class and restricting direct access to
some attributes. This protects the internal state and behavior of
an object from external interference.
Example:
Using encapsulation, we’ll modify our BankAccount example.
class BankAccount:
def __init__(self, balance):
self.__balance = balance # Private
attribute
def deposit(self, amount):
if amount > 0:
self.__balance += amount
By: Prof. Ganesh S. Wayal
ALARD UNIVERSITY
def withdraw(self, amount):
if amount > 0 and amount <=
self.__balance:
self.__balance -= amount
return amount
else:
print("Invalid transaction")
def get_balance(self):
return self.__balance
# Trying to access private attribute
account = BankAccount(1000)
print(account.get_balance()) # Output: 1000
Explanation:
● Encapsulation with Private Attributes: By making
__balance private, we encapsulate the balance data
within the class, preventing outside code from directly
modifying it.
● Controlled Access: deposit, withdraw, and
get_balance methods provide controlled ways to
interact with the balance.
By: Prof. Ganesh S. Wayal