Abstraction
Abstraction is the concept of hiding complex implementation details and showing only the essential features of an object. It helps reduce complexity and increase efficiency by allowing users to interact with objects at a higher level without worrying about internal implementation.
Understanding Abstraction
Section titled “Understanding Abstraction”Abstraction focuses on what an object does rather than how it does it. It provides a simplified interface to complex systems.
Real-World Analogy
Section titled “Real-World Analogy”Think of a car:
- What you see: Steering wheel, pedals, gear shift
- What’s hidden: Engine mechanics, transmission system, fuel injection
You don’t need to know how the engine works to drive the car - that’s abstraction!
Abstract Base Classes (ABC)
Section titled “Abstract Base Classes (ABC)”Python provides the abc module to create abstract classes. Abstract classes cannot be instantiated directly and must be subclassed.
Basic Abstract Class
Section titled “Basic Abstract Class”from abc import ABC, abstractmethod
class Shape(ABC): """Abstract base class - cannot be instantiated"""
@abstractmethod def area(self): """Abstract method - must be implemented by subclasses""" pass
@abstractmethod def perimeter(self): """Abstract method - must be implemented by subclasses""" pass
def describe(self): """Concrete method - can be used by all subclasses""" return f"Shape with area {self.area()} and perimeter {self.perimeter()}"
# This will raise TypeError# shape = Shape() # Can't instantiate abstract class
class Rectangle(Shape): """Concrete implementation of Shape""" def __init__(self, width: float, height: float): self.width = width self.height = height
def area(self): """Must implement abstract method""" return self.width * self.height
def perimeter(self): """Must implement abstract method""" return 2 * (self.width + self.height)
class Circle(Shape): """Concrete implementation of Shape""" def __init__(self, radius: float): self.radius = radius
def area(self): """Must implement abstract method""" import math return math.pi * self.radius ** 2
def perimeter(self): """Must implement abstract method""" import math return 2 * math.pi * self.radius
# Now we can create instancesrectangle = Rectangle(5, 3)print(rectangle.area()) # 15print(rectangle.describe()) # Uses inherited concrete method
circle = Circle(4)print(circle.area()) # ~50.27classDiagram
class Shape {
<<abstract>>
+area()* float
+perimeter()* float
+describe() str
}
class Rectangle {
-width: float
-height: float
+area() float
+perimeter() float
}
class Circle {
-radius: float
+area() float
+perimeter() float
}
Shape <|-- Rectangle
Shape <|-- Circle
note for Shape "Abstract class\nCannot be instantiated"
Real-World Example: Payment Processing
Section titled “Real-World Example: Payment Processing”from abc import ABC, abstractmethod
class PaymentProcessor(ABC): """Abstract base class for payment processing"""
@abstractmethod def process_payment(self, amount: float) -> bool: """Process a payment - must be implemented""" pass
@abstractmethod def refund(self, transaction_id: str) -> bool: """Process a refund - must be implemented""" pass
def validate_amount(self, amount: float) -> bool: """Concrete method - shared validation logic""" return amount > 0
class CreditCardProcessor(PaymentProcessor): """Concrete implementation for credit card payments""" def __init__(self, api_key: str): self.api_key = api_key
def process_payment(self, amount: float) -> bool: """Process credit card payment""" if not self.validate_amount(amount): return False # Credit card processing logic print(f"Processing ${amount} via credit card") return True
def refund(self, transaction_id: str) -> bool: """Process credit card refund""" print(f"Refunding transaction {transaction_id} via credit card") return True
class PayPalProcessor(PaymentProcessor): """Concrete implementation for PayPal payments""" def __init__(self, client_id: str, client_secret: str): self.client_id = client_id self.client_secret = client_secret
def process_payment(self, amount: float) -> bool: """Process PayPal payment""" if not self.validate_amount(amount): return False # PayPal processing logic print(f"Processing ${amount} via PayPal") return True
def refund(self, transaction_id: str) -> bool: """Process PayPal refund""" print(f"Refunding transaction {transaction_id} via PayPal") return True
class CryptoProcessor(PaymentProcessor): """Concrete implementation for cryptocurrency payments""" def __init__(self, wallet_address: str): self.wallet_address = wallet_address
def process_payment(self, amount: float) -> bool: """Process cryptocurrency payment""" if not self.validate_amount(amount): return False # Crypto processing logic print(f"Processing ${amount} via cryptocurrency") return True
def refund(self, transaction_id: str) -> bool: """Process cryptocurrency refund""" print(f"Refunding transaction {transaction_id} via cryptocurrency") return True
# Usage - abstraction allows treating all processors the same waydef checkout(processor: PaymentProcessor, amount: float): """Function works with any PaymentProcessor implementation""" return processor.process_payment(amount)
# All processors can be used interchangeablycredit_card = CreditCardProcessor("api_key_123")paypal = PayPalProcessor("client_id", "secret")crypto = CryptoProcessor("0x1234...")
checkout(credit_card, 100.0) # Workscheckout(paypal, 100.0) # Workscheckout(crypto, 100.0) # WorksAbstract Properties
Section titled “Abstract Properties”You can also define abstract properties:
from abc import ABC, abstractmethod
class Animal(ABC): """Abstract base class with abstract properties"""
@property @abstractmethod def name(self) -> str: """Abstract property - must be implemented""" pass
@property @abstractmethod def sound(self) -> str: """Abstract property - must be implemented""" pass
def make_sound(self): """Concrete method using abstract properties""" return f"{self.name} says {self.sound}"
class Dog(Animal): def __init__(self, name: str): self._name = name
@property def name(self) -> str: return self._name
@property def sound(self) -> str: return "Woof!"
class Cat(Animal): def __init__(self, name: str): self._name = name
@property def name(self) -> str: return self._name
@property def sound(self) -> str: return "Meow!"
dog = Dog("Buddy")print(dog.make_sound()) # "Buddy says Woof!"
cat = Cat("Whiskers")print(cat.make_sound()) # "Whiskers says Meow!"Benefits of Abstraction
Section titled “Benefits of Abstraction”Example: Database Abstraction
Section titled “Example: Database Abstraction”from abc import ABC, abstractmethod
class Database(ABC): """Abstract database interface"""
@abstractmethod def connect(self): """Establish database connection""" pass
@abstractmethod def execute_query(self, query: str): """Execute a database query""" pass
@abstractmethod def close(self): """Close database connection""" pass
def __enter__(self): """Context manager entry""" self.connect() return self
def __exit__(self, exc_type, exc_val, exc_tb): """Context manager exit""" self.close()
class PostgreSQLDatabase(Database): """PostgreSQL implementation""" def connect(self): print("Connecting to PostgreSQL...")
def execute_query(self, query: str): print(f"Executing PostgreSQL query: {query}")
def close(self): print("Closing PostgreSQL connection")
class MongoDBDatabase(Database): """MongoDB implementation""" def connect(self): print("Connecting to MongoDB...")
def execute_query(self, query: str): print(f"Executing MongoDB query: {query}")
def close(self): print("Closing MongoDB connection")
# Code works with any database implementationdef run_query(database: Database, query: str): """Function works with any Database implementation""" with database: database.execute_query(query)
postgres = PostgreSQLDatabase()mongodb = MongoDBDatabase()
run_query(postgres, "SELECT * FROM users")run_query(mongodb, 'db.users.find({})')Key Takeaways
Section titled “Key Takeaways”- Use abstraction to create flexible, maintainable code that can work with multiple implementations
Abstraction is about creating a contract that all implementations must follow, while hiding the complexity of how each implementation works internally.