Key aspects of abstraction include:
In many object-oriented languages, abstraction is implemented through abstract classes and interfaces. While Python doesn’t have a built-in interface concept, we can achieve similar functionality using abstract base classes. Python’s abc
module provides infrastructure for defining abstract base classes:
from abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
def area(self):
pass
@abstractmethod
def perimeter(self):
pass
class Rectangle(Shape):
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
def perimeter(self):
return 2 * (self.width + self.height)
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14159 * self.radius ** 2
def perimeter(self):
return 2 * 3.14159 * self.radius
# Usage
# shapes = [Shape()] # This would raise TypeError
shapes = [Rectangle(5, 4), Circle(3)]
for shape in shapes:
print(f"Area: {shape.area()}, Perimeter: {shape.perimeter()}")
# Output:
# Area: 20, Perimeter: 18
# Area: 28.27431, Perimeter: 18.84954
In this example:
Shape
is an abstract base class that defines the interface for all shapes.Rectangle
and Circle
are concrete classes that implement the Shape
interface.Shape
directly, but we can use it as a common type for all shapes.While abstract base classes provide a formal way to define interfaces in Python, abstraction can also be achieved through convention and documentation. Here’s an example of abstraction without using ABC
:
class Database:
def connect(self):
raise NotImplementedError("Subclass must implement abstract method")
def execute(self, query):
raise NotImplementedError("Subclass must implement abstract method")
class MySQLDatabase(Database):
def connect(self):
print("Connecting to MySQL database...")
def execute(self, query):
print(f"Executing MySQL query: {query}")
class PostgreSQLDatabase(Database):
def connect(self):
print("Connecting to PostgreSQL database...")
def execute(self, query):
print(f"Executing PostgreSQL query: {query}")
def perform_database_operation(database):
database.connect()
database.execute("SELECT * FROM users")
# Usage
mysql_db = MySQLDatabase()
postgres_db = PostgreSQLDatabase()
perform_database_operation(mysql_db)
perform_database_operation(postgres_db)
# Output:
# Connecting to MySQL database...
# Executing MySQL query: SELECT * FROM users
# Connecting to PostgreSQL database...
# Executing PostgreSQL query: SELECT * FROM users
In this example:
Database
is an abstract base class (though not using ABC
) that defines the interface for all database types.MySQLDatabase
and PostgreSQLDatabase
are concrete implementations.perform_database_operation
works with any object that adheres to the Database
interface.Abstraction is a key component of several important design principles and patterns:
SOLID Principles:
Design Patterns:
Let’s implement the Strategy Pattern as an example:
from abc import ABC, abstractmethod
class SortStrategy(ABC):
@abstractmethod
def sort(self, data):
pass
class BubbleSort(SortStrategy):
def sort(self, data):
print("Performing bubble sort")
return sorted(data) # Using Python's built-in sort for simplicity
class QuickSort(SortStrategy):
def sort(self, data):
print("Performing quick sort")
return sorted(data) # Using Python's built-in sort for simplicity
class Sorter:
def __init__(self, strategy):
self.strategy = strategy
def sort(self, data):
return self.strategy.sort(data)
# Usage
data = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]
bubble_sorter = Sorter(BubbleSort())
print(bubble_sorter.sort(data))
quick_sorter = Sorter(QuickSort())
print(quick_sorter.sort(data))
# Output:
# Performing bubble sort
# [1, 1, 2, 3, 3, 4, 5, 5, 5, 6, 9]
# Performing quick sort
# [1, 1, 2, 3, 3, 4, 5, 5, 5, 6, 9]
This Strategy Pattern example demonstrates how abstraction allows us to define a family of algorithms, encapsulate each one, and make them interchangeable. The Sorter
class doesn’t need to know the details of how each sorting algorithm works; it just knows that it can call the sort
method on any SortStrategy
object.
Cheers for making it this far! I hope this journey through the programming universe has been as fascinating for you as it was for me to write down.
We’re keen to hear your thoughts, so don’t be shy – drop your comments, suggestions, and those bright ideas you’re bound to have.
Also, to delve deeper than these lines, take a stroll through the practical examples we’ve cooked up for you. You’ll find all the code and projects in our GitHub repository learn-software-engineering/examples.
Thanks for being part of this learning community. Keep coding and exploring new territories in this captivating world of software!
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.