Skip to main content

Concept

Abstraction hides complex internal implementation details and shows only the essential features of an object. It lets developers focus on what to do rather than how to do it.
Abstraction vs Encapsulation:
  • Abstraction is about hiding complexity and showing only essential features.
  • Encapsulation is about hiding data and controlling access to an object’s internal state.
TypeDescription
Data AbstractionHides the details of data representation and focuses on essential properties.
Process AbstractionHides the implementation of operations and focuses on essential features of the process.
Control AbstractionHides the complexity of control flow and focuses on essential features of control structures.

Implementation

In Python, abstraction is achieved using Abstract Base Classes (ABC) from the abc module.
Abstract classes cannot be instantiated directly. They are meant to be subclassed, and the subclasses must implement all abstract methods defined in the abstract class. An abstract class can contain both abstract methods (without implementation) and concrete methods (with implementation).

Shape Example

shapes.py
from abc import ABC, abstractmethod

class Shape(ABC):
  @abstractmethod
  def area(self):
    pass

  @abstractmethod
  def perimeter(self):
    pass

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

# This will raise TypeError:
# shape = Shape()  # Can't instantiate abstract class

circle = Circle(5)
print(circle.area())       # Output: 78.53975
print(circle.perimeter())  # Output: 31.4159

Database Connection Example

Abstraction is especially useful for defining interfaces that can have multiple implementations — for example, supporting both MySQL and PostgreSQL behind a common interface.
database.py
from abc import ABC, abstractmethod

class DatabaseConnection(ABC):
  @abstractmethod
  def connect(self):
    pass

  @abstractmethod
  def execute_query(self, query):
    pass

  def get_user(self, user_id):  # Concrete method
    query = f"SELECT * FROM users WHERE id = {user_id}"
    return self.execute_query(query)

class MySQLConnection(DatabaseConnection):
  def connect(self):
    # MySQL-specific connection logic
    pass

  def execute_query(self, query):
    # MySQL-specific query execution
    pass

class PostgreSQLConnection(DatabaseConnection):
  def connect(self):
    # PostgreSQL-specific connection logic
    pass

  def execute_query(self, query):
    # PostgreSQL-specific query execution
    pass
The get_user() method is a concrete method on the abstract class — it contains shared logic that works for all database implementations, calling execute_query() which each subclass implements differently. This is the power of abstraction: define the what, let subclasses define the how.

Build docs developers (and LLMs) love