These notes serve as a complete guide to OOP concepts with detailed explanations and examples in Python.
1. Core Principles of OOP
Object-Oriented Programming is based on four fundamental principles:
1.1 Encapsulation
- Definition: Bundling data (attributes) and methods (functions) that operate on that data into a single unit (class) and restricting direct access to some of the object’s components.
- Goal: Protect the integrity of the data and expose only necessary details.
Example:
class BankAccount:
def __init__(self, balance):
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:
raise ValueError("Invalid withdrawal amount")
def get_balance(self):
return self.__balance
# Usage
account = BankAccount(1000)
account.deposit(500)
print(account.get_balance()) # 1500
1.2 Abstraction
- Definition: Hiding complex implementation details and showing only the necessary functionality.
- Goal: Reduce complexity and increase code usability.
Example:
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 ** 2
class Rectangle(Shape):
def __init__(self, length, width):
self.length = length
self.width = width
def area(self):
return self.length * self.width
# Usage
shapes = [Circle(5), Rectangle(4, 6)]
for shape in shapes:
print(shape.area())
1.3 Inheritance
- Definition: Allowing a class to acquire the properties and methods of another class.
- Goal: Promote code reuse and establish a hierarchical relationship between classes.
Example:
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
pass
class Dog(Animal):
def speak(self):
return f"{self.name} says Woof!"
class Cat(Animal):
def speak(self):
return f"{self.name} says Meow!"
# Usage
animals = [Dog("Buddy"), Cat("Whiskers")]
for animal in animals:
print(animal.speak())
1.4 Polymorphism
- Definition: The ability to present the same interface for different underlying forms (data types or classes).
- Goal: Write more generic and reusable code.
Example:
class Bird:
def fly(self):
return "Flying high"
class Penguin(Bird):
def fly(self):
return "I cannot fly, I swim!"
# Usage
birds = [Bird(), Penguin()]
for bird in birds:
print(bird.fly())
2. Key Concepts in OOP
2.1 Classes and Objects
- Class: A blueprint for creating objects.
- Object: An instance of a class containing data (attributes) and methods (functions).
Example:
class Car:
def __init__(self, brand, model):
self.brand = brand
self.model = model
def display_info(self):
return f"Car: {self.brand} {self.model}"
# Usage
car = Car("Toyota", "Corolla")
print(car.display_info())
2.2 Access Modifiers
- Public: Accessible from anywhere.
- Protected: Accessible within the class and its subclasses (convention:
_attribute). - Private: Accessible only within the class (convention:
__attribute).
Example:
class Example:
def __init__(self):
self.public = "Public"
self._protected = "Protected"
self.__private = "Private"
def get_private(self):
return self.__private
# Usage
obj = Example()
print(obj.public) # Public
print(obj._protected) # Protected (not recommended)
print(obj.get_private()) # Accessing private attribute via method
2.3 Method Overloading and Overriding
- Overloading: Same method name but different parameters (Python doesn’t natively support it; mimic it using default arguments).
- Overriding: Redefining a method in a subclass that exists in the parent class.
Overloading Example:
def add(a, b, c=0):
return a + b + c
# Usage
print(add(2, 3)) # 5
print(add(2, 3, 4)) # 9
Overriding Example:
class Parent:
def greet(self):
return "Hello from Parent"
class Child(Parent):
def greet(self):
return "Hello from Child"
# Usage
obj = Child()
print(obj.greet()) # Hello from Child
2.4 Composition vs Inheritance
- Inheritance: “Is-a” relationship (e.g., Dog is an Animal).
- Composition: “Has-a” relationship (e.g., Car has an Engine).
Composition Example:
class Engine:
def start(self):
return "Engine started"
class Car:
def __init__(self):
self.engine = Engine()
def start(self):
return self.engine.start()
# Usage
car = Car()
print(car.start()) # Engine started
3. SOLID Principles in OOP
3.1 Single Responsibility Principle (SRP)
- A class should have only one reason to change.
Example:
class ReportGenerator:
def generate_report(self, data):
return f"Report: {data}"
class ReportPrinter:
def print_report(self, report):
print(report)
3.2 Open/Closed Principle (OCP)
- Classes should be open for extension but closed for modification.
Example:
class Discount:
def calculate(self, amount):
return amount
class SeasonalDiscount(Discount):
def calculate(self, amount):
return amount * 0.9
class LoyaltyDiscount(Discount):
def calculate(self, amount):
return amount * 0.8
# Usage
discounts = [SeasonalDiscount(), LoyaltyDiscount()]
for discount in discounts:
print(discount.calculate(100))
3.3 Liskov Substitution Principle (LSP)
- Subtypes should be substitutable for their base types.
Example:
class Bird:
def fly(self):
return "Flying"
class Sparrow(Bird):
pass
class Ostrich(Bird):
def fly(self):
raise NotImplementedError("Ostriches cannot fly")
3.4 Interface Segregation Principle (ISP)
- Avoid forcing classes to implement methods they do not use.
Example:
from abc import ABC, abstractmethod
class Printer(ABC):
@abstractmethod
def print(self):
pass
class Scanner(ABC):
@abstractmethod
def scan(self):
pass
class MultiFunctionPrinter(Printer, Scanner):
def print(self):
return "Printing"
def scan(self):
return "Scanning"
3.5 Dependency Inversion Principle (DIP)
- High-level modules should not depend on low-level modules. Both should depend on abstractions.
Example:
class Database:
def save(self, data):
pass
class MySQLDatabase(Database):
def save(self, data):
print(f"Saving {data} in MySQL")
class Application:
def __init__(self, db: Database):
self.db = db
def save_data(self, data):
self.db.save(data)
# Usage
app = Application(MySQLDatabase())
app.save_data("User Data")