Python OOP: Classes, Inheritance, Polymorphism, and Encapsulation

Object-Oriented Programming (OOP) is a programming paradigm built around objects, which bundle data (attributes) and functions (methods). Python supports OOP features clearly, allowing programmers to create reusable, maintainable, and modular code.

The core principles of OOP include:

  • Classes and Objects
  • Inheritance
  • Polymorphism
  • Encapsulation

Let’s explore these concepts deeply, accompanied by clear explanations of examples.

1. Classes and Objects

A class in Python serves as a blueprint or a template for creating objects. Objects created from a class have attributes (data fields) and methods (behaviors).

Example:

class Student:
    # Constructor method to initialize instance variables
    def __init__(self, name, student_id, major):
        self.name = name
        self.student_id = student_id
        self.major = major
        self.grades = []

    # Method to add a grade
    def add_grade(self, grade):
        self.grades.append(grade)

    # Method to calculate average grade
    def calculate_average(self):
        if self.grades:
            return sum(self.grades) / len(self.grades)
        else:
            return 0.0

    # Method to display student information
    def info(self):
        avg_grade = self.calculate_average()
        return f"Student: {self.name}, ID: {self.student_id}, Major: {self.major}, Average Grade: {avg_grade:.2f}"

In the example above, the class Student has attributes like name, student_id, major, and grades. It also has methods to handle student behaviors like adding grades and calculating averages.

Creating Objects and Using Them
student1 = Student("Alice", "S001", "Physics")
student1.add_grade(85)
student1.add_grade(90)
student1.add_grade(95)

print(student1.info())

Explanation of the Code:

Here, we create an instance of the Student class named student1. We add three grades to this student’s record using the add_grade() method. Then, we display the student’s information, including the calculated average grade, using the info() method.

Output:

2. Inheritance

Inheritance allows a new class (called child or subclass) to derive properties and methods from an existing class (parent or superclass). This approach promotes code reuse and clean organization.

Example of Inheritance:

# Parent class
class Vehicle:
    def __init__(self, brand, model):
        self.brand = brand
        self.model = model

    def drive(self):
        print(f"The {self.brand} {self.model} is driving.")

# Child class inheriting from Vehicle
class ElectricCar(Vehicle):
    def __init__(self, brand, model, battery_capacity):
        super().__init__(brand, model)  # Calls parent constructor
        self.battery_capacity = battery_capacity

    # Overriding parent method
    def drive(self):
        print(f"The electric car {self.brand} {self.model} is silently driving.")

    # New method specific to ElectricCar
    def charge(self):
        print(f"Charging {self.brand} {self.model}'s battery ({self.battery_capacity} kWh).")

Creating Objects and Explanation:

tesla = ElectricCar("Tesla", "Model 3", 75)

tesla.drive()   # overridden method
tesla.charge()  # child-specific method

In this example, we create an ElectricCar object named tesla. It inherits attributes (brand, model) and methods (drive) from the parent Vehicle class. Additionally, ElectricCar has a specific attribute (battery_capacity) and method (charge). The drive() method is overridden to reflect the unique behavior of electric vehicles.

Output:

3. Polymorphism

Polymorphism means “many forms.” It enables objects of different classes to be treated as instances of the same parent class, allowing one interface to represent multiple underlying forms.

Example of Polymorphism:

class Animal:
    def __init__(self, name):
        self.name = name

    def speak(self):
        print("Animal makes a sound.")

class Dog(Animal):
    def speak(self):
        print(f"{self.name} says Woof!")

class Cat(Animal):
    def speak(self):
        print(f"{self.name} says Meow!")

def animal_sound(animal):
    animal.speak()

dog = Dog("Buddy")
cat = Cat("Whiskers")

animal_sound(dog)
animal_sound(cat)

Explanation of the Code:

Here, both Dog and Cat inherit from Animal and override the speak() method. The function animal_sound() takes an animal object and calls its speak() method. Python dynamically decides at runtime which method (Dog or Cat) to execute, demonstrating polymorphism clearly.

Output:

4. Encapsulation

Encapsulation bundles data (attributes) and methods that operate on the data within a class. It restricts direct access to some of the object’s components, protecting data integrity and enhancing security.

Example of Encapsulation:

class BankAccount:
    def __init__(self, account_holder, balance=0):
        self.account_holder = account_holder
        self.__balance = balance  # private attribute

    def deposit(self, amount):
        if amount > 0:
            self.__balance += amount

    def withdraw(self, amount):
        if 0 < amount <= self.__balance:
            self.__balance -= amount
        else:
            print("Insufficient funds.")

    def get_balance(self):
        return self.__balance

Explanation of Encapsulation Example:

In the code above, the __balance attribute is private (indicated by the double underscore). It cannot be directly accessed or modified from outside the class. Instead, we provide public methods (deposit(), withdraw(), and get_balance()) to control how the balance can be accessed or updated, ensuring data integrity and security.

Usage Example:

account = BankAccount("Alice", 500)
account.deposit(200)
account.withdraw(100)

print(f"Balance: ${account.get_balance()}")

# Direct access will result in error
# print(account.__balance) # This raises an AttributeError

Output:

  • Classes & Objects organize data and behavior.
  • Inheritance allows reuse of common properties and methods.
  • Polymorphism ensures the same interface for different object types.
  • Encapsulation protects data and controls its access.

By mastering these fundamental OOP concepts in Python, you’ll be equipped to create efficient, maintainable, and scalable software.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top