SOLID Principles: The Foundation of OOP Design

1. Single Responsibility Principle (SRP)

A class should have one and only one reason to change, meaning it should have only one job.

2. Open/Closed Principle (OCP)

Software entities should be open for extension but closed for modification. Use inheritance or interfaces to add new behavior without altering existing code.

3. Liskov Substitution Principle (LSP)

Objects of a superclass should be replaceable with objects of a subclass without affecting correctness.

class Bird:
    def fly(self): return "Flying"

class Duck(Bird):  # OK
    pass

class Penguin(Bird):  # Violates LSP — penguins can't fly!
    def fly(self): raise NotImplementedError

4. Interface Segregation Principle (ISP)

Clients should not be forced to depend on interfaces they do not use. Prefer multiple small, specific interfaces over one large, general-purpose interface.

5. Dependency Inversion Principle (DIP)

High-level modules should not depend on low-level modules; both should depend on abstractions. Abstractions should not depend on details; details should depend on abstractions.