Procedural vs OOP, Classes, Objects, Encapsulation & Abstraction
Python is a multi-paradigm programming language — it supports both Procedural Programming (using functions) and Object-Oriented Programming (OOP) (using classes and objects).
1. Procedural vs Object-Oriented Programming (OOP)
| Feature | Procedural Programming (POP) | Object-Oriented Programming (OOP) |
|---|---|---|
| Basic Unit | Program is divided into small Functions / Procedures | Program is organized around Classes and Objects |
| Focus | Focuses on “How to do” (Algorithm / Sequence of steps) | Focuses on “Data and Security” (Real-world entities) |
| Data & Functions | Data and functions are separate; global data moves freely between functions | Data (attributes) and functions (methods) are bound together inside a single unit (Object) |
| Data Security | Low Security: Any function can accidentally modify global data | High Security: Supports Data Hiding / Encapsulation using private variables |
| Approach | Follows a Top-Down approach | Follows a Bottom-Up approach |
| Code Reusability | Limited to calling existing functions | Very high via Inheritance and Polymorphism |
| Examples | C, Pascal, Fortran | Python, Java, C++, C# |
2. Classes, Objects, __init__() Constructor & self
- Class: A logical blueprint or template for creating objects. It defines what properties (variables) and behaviors (methods) an object will have.
- Object: A real-world instance of a class that occupies memory.
__init__()Method (Constructor): A special magic method that runs automatically whenever a new object of the class is created, used to initialize object variables.selfKeyword: Refers to the current object instance calling the method (similar tothisin C++/Java).
class Student:
# Constructor to initialize object attributes
def __init__(self, roll_no, name, marks):
self.roll_no = roll_no
self.name = name
self.marks = marks
# Method (behavior)
def display_info(self):
print(f"Roll: {self.roll_no} | Name: {self.name} | Marks: {self.marks}")
# Creating Objects (Instances) of Student class
s1 = Student(101, "Aarav", 88)
s2 = Student(102, "Diya", 94)
s1.display_info() # Roll: 101 | Name: Aarav | Marks: 88
s2.display_info() # Roll: 102 | Name: Diya | Marks: 94
3. Principle 1: Encapsulation & Data Hiding
Encapsulation is the process of binding data (variables) and the methods (functions) that operate on that data into a single unit (Class), while protecting sensitive data from unauthorized direct external modification (Data Hiding).
Real-World Analogy: A medical capsule wraps multiple medicines inside a protective shell so they cannot be tampered with from the outside.
Access Specifiers in Python (Public, Protected, Private):
Unlike Java/C++, Python does not use public, protected, or private keywords. Instead, it uses underscore prefixes:
| Access Modifier | Syntax | Accessibility |
|---|---|---|
| 1. Public | self.name (No underscore) |
Accessible from anywhere (inside and outside the class) |
| 2. Protected | self._salary (Single underscore _) |
Accessible within the class and its subclasses (child classes) |
| 3. Private | self.__balance (Double underscore __) |
Accessible ONLY inside the class (Enforces Data Hiding!) |
Example of Encapsulation & Private Variable (__balance):
class BankAccount:
def __init__(self, owner, balance):
self.owner = owner # Public variable
self.__balance = balance # Private variable (Data Hiding with __)
# Public Setter method to safely deposit money
def deposit(self, amount):
if amount > 0:
self.__balance += amount
print(f"Deposited Rs.{amount} successfully.")
# Public Getter method to check balance
def get_balance(self):
return self.__balance
acc = BankAccount("Rohit", 5000)
acc.deposit(2000)
print("Current Balance:", acc.get_balance()) # Output: 7000
# Trying to access private variable directly outside the class raises AttributeError!
# print(acc.__balance) --> AttributeError: 'BankAccount' object has no attribute '__balance'
4. Principle 2: Abstraction in Python
Abstraction means hiding complex internal implementation details from the user and exposing only the necessary functionality (interface).
- Real-World Example: When you press the brake pedal in a car, the car stops. You don’t need to know how the internal hydraulic disc brakes work!
How to Achieve Abstraction in Python (abc Module):
Python provides the built-in abc (Abstract Base Classes) module.
- A class that inherits from
ABCand contains at least one@abstractmethodis called an Abstract Class. - You cannot create an object of an Abstract Class directly; child classes must implement its abstract methods.
from abc import ABC, abstractmethod
# Abstract Class (Blueprint / Interface)
class PaymentGateway(ABC):
@abstractmethod
def pay(self, amount):
pass # No implementation here; child classes MUST implement this
class UPIPayment(PaymentGateway):
def pay(self, amount):
print(f"Paid Rs.{amount} securely using UPI.")
class CardPayment(PaymentGateway):
def pay(self, amount):
print(f"Paid Rs.{amount} using Credit/Debit Card.")
# Using Abstraction
p1 = UPIPayment()
p1.pay(500) # Output: Paid Rs.500 securely using UPI.
p2 = CardPayment()
p2.pay(1200) # Output: Paid Rs.1200 using Credit/Debit Card.