Python Object-Oriented Programming exercises help in understanding classes, objects, inheritance, encapsulation, polymorphism and other features through practical problems. This collection starts with basic class-based programs and gradually moves to coding problems commonly used in interviews.
- Each exercise focuses on a specific OOP concept.
- The questions include practical and edge-case based problems.
- Later exercises combine multiple OOP concepts in a single program.
Example Programs
Exercise 1: Create a class Student with attributes name and marks. Create an object and display the student's details.
class Student:
def __init__(self, name, marks):
self.name = name
self.marks = marks
def display(self):
print("Name:", self.name)
print("Marks:", self.marks)
student = Student("Rahul", 85)
student.display()
Output
Name: Rahul Marks: 85
Explanation:
- Student class stores the student's name and marks.
- display() method prints the values stored in the object.
- Object student represents one student created from the class.
Exercise 2: Create a class Employee with a class variable company and an instance variable name. Display the details of two employees.
class Employee:
company = "TechCorp"
def __init__(self, name):
self.name = name
def display(self):
print(self.name, "-", self.company)
emp1 = Employee("Amit")
emp2 = Employee("Neha")
emp1.display()
emp2.display()
Output
Amit - TechCorp Neha - TechCorp
Explanation:
- Company is shared by all Employee objects.
- Name is stored separately for each object.
- Both objects access the same class variable.
Exercise 3: Create a BankAccount class with methods to deposit money, withdraw money and display the current balance. Preventing withdrawal when the balance is insufficient.
class BankAccount:
def __init__(self, balance=0):
self.balance = balance
def deposit(self, amount):
self.balance += amount
def withdraw(self, amount):
if amount <= self.balance:
self.balance -= amount
else:
print("Insufficient balance")
def display_balance(self):
print("Balance:", self.balance)
account = BankAccount(1000)
account.deposit(500)
account.withdraw(300)
account.display_balance()
Output
Balance: 1200
Explanation:
- Balance is updated whenever money is deposited or withdrawn.
- Withdrawal is allowed only when sufficient balance is available.
- Constructor provides an initial balance.
Exercise 4: Create a class UserAccount with a private password attribute. Providing a method to change the password only when the old password is correct.
class UserAccount:
def __init__(self, password):
self.__password = password
def change_password(self, old_password, new_password):
if self.__password == old_password:
self.__password = new_password
print("Password changed successfully")
else:
print("Incorrect password")
user = UserAccount("abc123")
user.change_password("abc123", "xyz789")
user.change_password("abc123", "new456")
Output
Password changed successfully Incorrect password
Explanation:
- Password is stored using a private attribute.
- Password can be changed only through the change_password() method.
- Second attempt fails because the old password is no longer valid.
Exercise 5: Create a Product class with a price property. The price should not accept negative values.
class Product:
def __init__(self, price):
self.price = price
@property
def price(self):
return self.__price
@price.setter
def price(self, value):
if value < 0:
print("Price cannot be negative")
else:
self.__price = value
product = Product(500)
print("Price:", product.price)
product.price = -100
print("Price:", product.price)
Output
Price: 500 Price cannot be negative Price: 500
Explanation:
- Property controls how the price is accessed and modified.
- Negative values are rejected by the setter.
- Existing valid price remains unchanged after an invalid assignment.
Exercise 6: Create a Vehicle class with a method start(). Create a Car class that inherits from Vehicle and adds a drive() method.
class Vehicle:
def start(self):
print("Vehicle started")
class Car(Vehicle):
def drive(self):
print("Car is driving")
car = Car()
car.start()
car.drive()
Explanation:
- Car inherits the start() method from Vehicle.
- Car also defines its own drive() method.
- Object can use methods from both classes.
Exercise 7: Create a parent class Animal with a sound() method. Overriding this method in Dog and Cat classes.
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")
dog = Dog()
cat = Cat()
dog.sound()
cat.sound()
Output
Dog barks Cat meows
Explanation:
- Both child classes provide their own implementation of sound().
- Method called depends on the object's class.
- This demonstrates runtime polymorphism.
Exercise 8: Create different payment classes such as CreditCard and UPI. Each class should implement a pay() method. Writing a function that works with either object.
class CreditCard:
def pay(self, amount):
print("Paid", amount, "using Credit Card")
class UPI:
def pay(self, amount):
print("Paid", amount, "using UPI")
def make_payment(payment_method, amount):
payment_method.pay(amount)
make_payment(CreditCard(), 500)
make_payment(UPI(), 300)
Output
Paid 500 using Credit Card Paid 300 using UPI
Explanation:
- Function does not need to know the exact class of the object.
- It only expects the object to provide a pay() method.
- This demonstrates polymorphism through common behavior.
Exercise 9: Create a Point class and overload the + operator so that two Point objects can be added together.
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __add__(self, other):
return Point(self.x + other.x, self.y + other.y)
def display(self):
print("(", self.x, ",", self.y, ")")
p1 = Point(2, 3)
p2 = Point(4, 5)
p3 = p1 + p2
p3.display()
Output
( 6 , 8 )
Explanation:
- add() method defines how the + operator works for Point objects.
- x and y coordinates of both objects are added separately.
- A new Point object is returned.
Exercise 10: Create a Book class and implement str() so that printing the object displays meaningful information instead of the default object representation.
class Book:
def __init__(self, title, author):
self.title = title
self.author = author
def __str__(self):
return f"{self.title} by {self.author}"
book = Book("Python Programming", "John")
print(book)
Output
Python Programming by John
Explanation:
- str() controls the string representation shown when the object is printed.
- Without str(), Python would display the default object representation.
Exercise 11: Create a class Employee that keeps track of how many Employee objects have been created.
class Employee:
count = 0
def __init__(self, name):
self.name = name
Employee.count += 1
emp1 = Employee("A")
emp2 = Employee("B")
emp3 = Employee("C")
print("Total employees:", Employee.count)
Explanation:
- Count is a class variable shared by all Employee objects.
- Constructor increments count whenever a new object is created.
- Final value represents the number of objects created.
Exercise 12: Create a Student class that stores marks and returns the highest mark. Handle the case where no marks are provided.
class Student:
def __init__(self, marks):
self.marks = marks
def highest_mark(self):
if not self.marks:
return "No marks available"
return max(self.marks)
student1 = Student([78, 92, 85])
student2 = Student([])
print(student1.highest_mark())
print(student2.highest_mark())
Output
92 No marks available
Explanation:
- The method checks whether the marks list is empty before calling max().
- This prevents an exception when no marks are available.
Exercise 13: Create an Engine class and a Car class. The Car should create and use an Engine object.
class Engine:
def start(self):
print("Engine started")
class Car:
def __init__(self):
self.engine = Engine()
def start(self):
self.engine.start()
print("Car started")
car = Car()
car.start()
Output
Engine started Car started
Explanation:
- Car contains an Engine object as one of its attributes.
- Starting the car uses the Engine object's start() method.
- This demonstrates composition between classes.
Exercise 14: Create an abstract Shape class with an area() method. Create Circle and Rectangle classes that provide their own implementations.
from abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
def area(self):
pass
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14 * self.radius * self.radius
class Rectangle(Shape):
def __init__(self, length, width):
self.length = length
self.width = width
def area(self):
return self.length * self.width
circle = Circle(5)
rectangle = Rectangle(4, 6)
print("Circle area:", circle.area())
print("Rectangle area:", rectangle.area())
Output
Circle area: 78.5 Rectangle area: 24
Explanation:
- Shape defines area() as an abstract method.
- Circle and Rectangle provide their own implementations.
- Common interface allows different shape objects to calculate their area differently.
Exercise 15: Create an Employee class with a basic salary. Create a Manager class that inherits from Employee and adds a bonus. Calculate the final salary.
class Employee:
def __init__(self, salary):
self.salary = salary
def total_salary(self):
return self.salary
class Manager(Employee):
def __init__(self, salary, bonus):
super().__init__(salary)
self.bonus = bonus
def total_salary(self):
return self.salary + self.bonus
employee = Employee(30000)
manager = Manager(50000, 10000)
print("Employee Salary:", employee.total_salary())
print("Manager Salary:", manager.total_salary())
Output
Employee Salary: 30000 Manager Salary: 60000
Explanation:
- Employee provides the basic salary calculation.
- Manager overrides total_salary() to include the bonus.
- super() is used to initialize the inherited salary attribute.
Exercise 16: Create a Product class and a ShoppingCart class. The cart should allow products to be added and calculate the total price.
class Product:
def __init__(self, name, price):
self.name = name
self.price = price
class ShoppingCart:
def __init__(self):
self.products = []
def add_product(self, product):
self.products.append(product)
def total_price(self):
return sum(product.price for product in self.products)
cart = ShoppingCart()
cart.add_product(Product("Laptop", 50000))
cart.add_product(Product("Mouse", 1000))
cart.add_product(Product("Keyboard", 2000))
print("Total:", cart.total_price())
Output
Total: 53000
Explanation:
- Product stores the details of individual products.
- ShoppingCart maintains a collection of Product objects.
- total_price() method calculates the combined price of all products.
- Program demonstrates object composition and interaction between classes.
Exercise 17: Create a diamond inheritance structure and use super() to observe the order in which constructors are called.
class A:
def __init__(self):
print("A")
class B(A):
def __init__(self):
super().__init__()
print("B")
class C(A):
def __init__(self):
super().__init__()
print("C")
class D(B, C):
def __init__(self):
super().__init__()
print("D")
D()
Output
A C B D
Explanation:
- D inherits from both B and C.
- super() follows the Method Resolution Order rather than simply calling the direct parent.
- Order demonstrates how cooperative multiple inheritance works in Python.
Exercise 18: Create a Library class that stores books and allows users to borrow and return them. A book should not be borrowed if it is already issued.
class Book:
def __init__(self, title):
self.title = title
self.available = True
class Library:
def __init__(self):
self.books = []
def add_book(self, book):
self.books.append(book)
def borrow_book(self, title):
for book in self.books:
if book.title == title:
if book.available:
book.available = False
print(title, "borrowed")
else:
print(title, "is already issued")
return
print("Book not found")
def return_book(self, title):
for book in self.books:
if book.title == title:
book.available = True
print(title, "returned")
return
print("Book not found")
library = Library()
library.add_book(Book("Python"))
library.add_book(Book("Data Structures"))
library.borrow_book("Python")
library.borrow_book("Python")
library.return_book("Python")
Output
Python borrowed Python is already issued Python returned
Explanation:
- Book stores the state of an individual book.
- Library manages multiple Book objects.
- Available attribute prevents the same book from being borrowed twice.
- Program combines classes, objects, composition and state management.