Python  

What are the four pillars of OOP in Python?

🔹 Introduction

Python allows us to organize our code using Object-Oriented Programming (OOP). Instead of writing everything in one place, OOP helps us build classes (blueprints) and objects (real things created from the class). To fully understand OOP in Python, we must know its four pillars: Encapsulation, Abstraction, Inheritance, and Polymorphism. These four ideas make our code structured, reusable, and easy to understand.

🛡️ Encapsulation

Encapsulation means putting variables (data) and functions (methods) that work with that data inside one unit, called a class. This helps us protect sensitive data and control how it is accessed.

  • Public members: Can be used anywhere in the program.
  • Protected members: Written with a single underscore _variable. This tells other programmers it should not be changed directly, though Python doesn’t stop it.
  • Private members: Written with two underscores __variable. These cannot be accessed directly from outside the class.

Example:

class BankAccount:
    def __init__(self, account_number, balance):
        self._account_number = account_number   # protected
        self.__balance = balance               # private

    def deposit(self, amount):
        self.__balance += amount
        print(f"Deposited {amount}, New Balance: {self.__balance}")

    def get_balance(self):
        return self.__balance

# Usage
account = BankAccount("12345", 1000)
account.deposit(500)
print(account.get_balance())  # Works fine
# print(account.__balance)    # Error: Cannot access private variable

Encapsulation makes sure that the balance cannot be directly changed from outside. Instead, we use methods like deposit() and get_balance().

🎭 Abstraction

Abstraction means hiding unnecessary details and only showing the important parts. When we use something, we don’t need to know exactly how it works inside.

In Python, abstraction can be done using abstract classes. These are classes that only provide a blueprint and leave the details to child classes. To do this, Python uses the abc module.

Example:

from abc import ABC, abstractmethod

class Vehicle(ABC):
    @abstractmethod
    def start(self):
        pass

class Car(Vehicle):
    def start(self):
        print("Car engine started.")

class Bike(Vehicle):
    def start(self):
        print("Bike engine started.")

# Usage
vehicles = [Car(), Bike()]
for v in vehicles:
    v.start()

Here, Vehicle is an abstract class. It says that every vehicle must have a start method, but it doesn’t say how. The classes Car and Bike provide the details.

🧬 Inheritance

Inheritance means a class can use the properties and methods of another class. The class that gives its properties is called the parent class, and the class that uses them is the child class. This helps us reuse code and avoid rewriting the same thing.

  • Single Inheritance: One child class inherits from one parent class.
  • Multiple Inheritance: One child class inherits from more than one parent class.
  • Multilevel Inheritance: A child inherits from a parent, and another child inherits from that child.

Example:

class Animal:
    def sound(self):
        print("Animals make sounds")

class Dog(Animal):
    def sound(self):
        print("Dog barks")

class Cat(Animal):
    def sound(self):
        print("Cat meows")

# Usage
d = Dog()
c = Cat()
d.sound()  # Dog barks
c.sound()  # Cat meows

Here, both Dog and Cat inherit from Animal. They override the sound() method to make it specific.

🔄 Polymorphism

Polymorphism means one thing having many forms. In programming, it means different classes can use the same method name, but they do different things.

Python supports polymorphism in two ways:

  • Method overriding: A child class changes the behavior of a method from the parent class.
  • Duck typing: If an object behaves like another (for example, it has the same method), Python treats it the same way.

Example:

class Bird:
    def fly(self):
        print("Most birds can fly")

class Penguin(Bird):
    def fly(self):
        print("Penguins cannot fly, but they swim well")

# Usage
birds = [Bird(), Penguin()]
for b in birds:
    b.fly()

Here, both Bird and Penguin have the fly() method. But they perform different actions when called. This is polymorphism.

🏁 Summary

The four pillars of OOP in Python are Encapsulation, Abstraction, Inheritance, and Polymorphism. Encapsulation helps protect data, abstraction hides complex details, inheritance allows code reuse, and polymorphism lets the same method name behave differently in different situations. Together, these pillars make Python code more organized, secure, and easy to maintain.