Skip to main content

Object-Oriented Programming (OOP) in Python: A Complete Guide with Examples

Introduction to Object-Oriented Programming (OOP) in Python

Object-Oriented Programming (OOP) is a programming paradigm that organizes code into objects, making it modular, reusable, and easier to maintain. Python supports OOP and provides features like classes, objects, inheritance, polymorphism, and encapsulation.



Why Use OOP?

OOP helps in:

  • Structuring code efficiently.

  • Reducing redundancy using inheritance.

  • Enhancing security through encapsulation.

  • Improving code maintainability and scalability.


Core Concepts of OOP in Python

1. Classes and Objects

class is a blueprint for creating objects. An object is an instance of a class.

Example of a Class and Object:

python
class Car
: def __init__(self, brand, model, year)
: self.brand = brand self.model = model self.year = year def display_info(self): 
print(f"Car: {self.brand} {self.model} ({self.year})") 
# Creating an object car1 = Car("Toyota", "Camry", 2023
car1.display_info()

Explanation:

  • The Car class has a constructor (__init__) that initializes attributes.

  • The display_info() method prints the car details.

  • car1 is an instance (object) of the Car class.


2. Encapsulation

Encapsulation restricts access to data and methods, protecting it from unintended modifications.

Example of Encapsulation:

python
class BankAccount
def __init__(self, account_number, balance): 
 self.account_number = account_number 
# Public attribute 
 self.__balance = balance
# Private attribute 
def deposit(self, amount):
 self.__balance += amount
print(f"Deposited {amount}.
 New balance: {self.__balance}")
def withdraw(self, amount): 
if amount <= self.__balance: self.__balance -= amount 
print(f"Withdrew {amount}
Remaining balance: {self.__balance}") 
else: print("Insufficient balance!") def get_balance(self):
return self.__balance 
# Accessing private attribute # Creating an object 
acc = BankAccount("12345", 5000) acc.deposit(2000
acc.withdraw(1000) print("Balance:", acc.get_balance()) 
# Trying to access private attribute directly (will cause error)
# print(acc.__balance) # Uncommenting this will cause an AttributeError

Explanation:

  • __balance is a private attribute.

  • It can only be modified using class methods (deposit()withdraw()).

  • Direct access to __balance outside the class is restricted.


3. Inheritance

Inheritance allows a class to derive properties and behavior from another class.

Example of Inheritance:

python
class Animal
def __init__(self, name): 
 self.name = name 
def make_sound(self): 
print("Some generic animal sound")
# Derived class 
class Dog(Animal):
def make_sound(self):
print("Bark! Bark!")
# Derived class 
class Cat(Animal):
def make_sound(self): 
print("Meow! Meow!"
 dog = Dog("Buddy"
dog.make_sound() 
# Output: Bark! Bark! 
 cat = Cat("Whiskers"
cat.make_sound() 
# Output: Meow! Meow!

Explanation:

  • The Animal class is the parent class.

  • Dog and Cat classes inherit from Animal and override the make_sound() method.


4. Polymorphism

Polymorphism allows different classes to have methods with the same name but different implementations.

Example of Polymorphism:

python
class Bird
def fly(self): 
print("Bird is flying"
class Airplane: def fly(self):
print("Airplane is flying in the sky") class Superhero: def fly(self): print("Superhero is flying to save the world!"
# Using polymorphism def make_it_fly(obj): 
 obj.fly() bird = Bird() 
plane = Airplane() hero = Superhero() make_it_fly(bird) 
# Output: Bird is flying make_it_fly(plane)
# Output: Airplane is flying in the sky make_it_fly(hero) 
# Output: Superhero is flying to save the world!

Explanation:

  • All three classes (BirdAirplaneSuperhero) have a fly() method.

  • The make_it_fly() function calls fly() on different objects without knowing their specific class.


5. Abstraction

Abstraction hides implementation details and only shows relevant functionalities.

Example of Abstraction using ABC module:

python
from abc import ABC, abstractmethod class Vehicle(ABC): @abstractmethod 
def start_engine(self): 
pass class Car(Vehicle):
def start_engine(self): 
print("Car engine started"
class Bike(Vehicle): 
def start_engine(self): 
print("Bike engine started"
 car = Car() car.start_engine() 
# Output: Car engine started 
 bike = Bike() bike.start_engine()
# Output: Bike engine started

Explanation:

  • Vehicle is an abstract class with an abstract method start_engine().

  • Car and Bike implement start_engine(), ensuring abstraction.


OOP Implementation: Real-World Example

Let's create a Library Management System using OOP principles.

python
class Book:
def __init__(self, title, author): self.title = title
 self.author = author self.is_borrowed = False def display_info(self): 
 status = "Available" 
if not self.is_borrowed
else "Borrowed" 
print(f"Title: {self.title}
Author: {self.author}
Status: {status}") 
class Library
def __init__(self): self.books = [] 
def add_book(self, book): self.books.append(book) 
print(f"Book '{book.title}'
 added to the library.") 
def borrow_book(self, title):
for book in self.books: 
if book.title == title 
and not book.is_borrowed: book.is_borrowed = 
True print(f"You borrowed '{title}'.")
return print("Book not available!")
def return_book(self, title): 
for book in self.books: 
if book.title == title
and book.is_borrowed: 
 book.is_borrowed = False print(f"You returned '{title}'.") 
return print("Invalid return attempt!") def display_books(self):
print("\nLibrary Collection:")
for book in self.books: book.display_info() 
# Creating book objects
book1 = Book("Python Programming", "John Doe") book2 = Book("Data Structures", "Jane Smith"
# Creating library object 
library = Library() library.add_book(book1) library.add_book(book2)
# Displaying books library.display_books()
# Borrowing and returning books library.borrow_book("Python Programming") library.display_books()
 library.return_book("Python Programming") library.display_books()

Explanation:

  • Book class manages book details.

  • Library class manages book operations like adding, borrowing, and returning books.


Conclusion

OOP in Python enhances code structure, making it modular and reusable. Understanding classes, objects, inheritance, polymorphism, encapsulation, and abstraction is key to mastering OOP.

This post provided a comprehensive introduction to OOP concepts along with real-world examples. Keep practicing to strengthen your understanding