Skip to content

Abstract Base Classes (ABCs)

Sometimes you want to define a “template” class that should never be used on its own. For example, you might have a PaymentProcessor class, but you only want people to use StripeProcessor or PayPalProcessor.

In Python, we use Abstract Base Classes (ABCs) to define a required interface that all subclasses must follow.


An abstract class cannot be instantiated. It exists only to be inherited from.

abc_demo.py
from abc import ABC, abstractmethod
class Database(ABC):
@abstractmethod
def connect(self):
"""Must be implemented by child"""
pass
@abstractmethod
def query(self, sql):
"""Must be implemented by child"""
pass
# db = Database() # Raises TypeError: Can't instantiate abstract class

If a subclass does not implement all methods marked with @abstractmethod, Python will refuse to create any instances of that subclass.

implementation.py
class MySQL(Database):
def connect(self):
print("Connecting to MySQL...")
# We forgot to implement 'query'!
# This class is still considered "Abstract"
# m = MySQL() # Raises TypeError

3. Virtual Subclasses: The register() Method

Section titled “3. Virtual Subclasses: The register() Method”

Normally, inheritance is explicit: class B(A). However, sometimes you have a class that already implements the required methods, but you don’t want to change its code to inherit from your ABC.

You can “register” it as a Virtual Subclass.

registration.py
class CustomLegacyDB:
def connect(self): pass
def query(self, sql): pass
# Register it as a subclass of Database
Database.register(CustomLegacyDB)
legacy = CustomLegacyDB()
print(isinstance(legacy, Database)) # Output: True!

Context: This is useful for third-party libraries where you cannot modify the source code but want them to work with your type-checking logic.


How does ABC work? It uses a special Metaclass called ABCMeta.

When you try to create an instance, the metaclass checks a hidden set of all methods that are marked as abstract. If that set is not empty, it blocks the creation. It also manages the “registry” of virtual subclasses, allowing isinstance() to work even when there’s no physical inheritance.


FeatureStandard ClassAbstract Base Class
InstantiationYes.No.
Abstract MethodsNot supported.Required via @abstractmethod.
PurposeConcrete implementation.Interface definition/Contract.
EnforcementNone.Blocks creation of incomplete children.