Skip to main content

Python Abstract Base Classes: Enforce Interfaces with ABC

Advanced25 min5 exercises85 XP
0/5 exercises

Imagine you're an architect handing blueprints to a construction crew. The blueprint says "there must be a front door here" and "the roof goes here." The crew can choose the materials and style, but they must include those parts. If they skip the front door, the building inspector will reject the project.

Abstract Base Classes (ABCs) work the same way in Python. They let you create a blueprint for other classes, forcing them to implement specific methods. If a subclass forgets one, Python raises an error immediately — not later when things break in production.

In this tutorial, you'll learn how to define abstract classes, require methods with @abstractmethod, create abstract properties, and decide when ABCs are the right tool versus Python's flexible duck typing.

What Is an Abstract Class?

A regular class is like a cookie cutter — you stamp it and get an object. An abstract class is different. It's a template that says "every cookie must have these features," but you can't use the template directly to make a cookie.

In technical terms, an abstract class is a class that cannot be instantiated on its own. It exists only to be inherited by other classes, which must fill in the missing pieces.

Why would you want a class you can't create objects from? Because it gives you a contract. Any class that inherits from it is guaranteed to have certain methods. This makes large codebases much more predictable.

The old way: errors hide until runtime
Loading editor...

The problem above is that you only discover the missing method when the code runs and someone calls area(). In a big project, that could be months later. ABCs catch this immediately.

How Do You Create an Abstract Class with ABC?

Python's abc module gives you two things: the ABC base class and the @abstractmethod decorator. Import them, inherit from ABC, and mark any methods that subclasses must implement.

Your first abstract class
Loading editor...

Python refuses to create a Shape object because it has abstract methods. Now let's create a proper subclass that implements everything.

A complete concrete subclass
Loading editor...

Notice that describe() is a regular method on the abstract class. It's not abstract, so subclasses inherit it for free. You can mix abstract methods (must override) with concrete methods (shared behavior) in the same class.

What happens when you skip a method
Loading editor...

Can You Make Abstract Properties?

Sometimes you don't just want subclasses to implement methods — you want them to provide specific properties too. You can combine @property with @abstractmethod to require this.

Abstract properties in action
Loading editor...

Abstract properties are useful when every subclass must have a certain attribute, but each subclass computes or stores it differently. The abstract class can use these properties in its own concrete methods, trusting that subclasses will provide them.


When Should You Use ABCs vs Duck Typing?

Python is famous for duck typing: "if it walks like a duck and quacks like a duck, it's a duck." You don't need a formal interface — if an object has the right methods, it works.

So when should you reach for ABCs instead? ABCs shine when you're building a framework or a library that other people will extend. They provide clear documentation about what's required and give immediate feedback when something is missing.

Duck Typing (informal)
# No enforcement — just hope for the best
class PaymentProcessor:
    def charge(self, amount):
        raise NotImplementedError

# Forgot charge()? No error until runtime
ABC (enforced)
from abc import ABC, abstractmethod

class PaymentProcessor(ABC):
    @abstractmethod
    def charge(self, amount):
        pass

# Forgot charge()? Instant TypeError

You can also use isinstance() checks with ABCs. When a class inherits from your ABC, isinstance() returns True, making it easy to validate objects at runtime.

Using isinstance() with ABCs
Loading editor...

What Are Some Real-World ABC Patterns?

ABCs really shine in plugin systems. Imagine you're building a notification service that can send messages through email, SMS, or push notifications. You define an ABC that every notification plugin must follow.

Plugin system with ABCs
Loading editor...

The send_alert function doesn't care which type of notifier it gets — it just knows that any Notifier subclass will have a send() method. This is the power of programming to an interface.

Python's own standard library uses ABCs extensively. The collections.abc module defines abstract classes like Iterable, Mapping, and Sequence. When you create a custom collection, inheriting from these ABCs tells Python (and other developers) exactly what your class supports.

ABCs in the standard library
Loading editor...

Practice Exercises

Create an Animal ABC
Write Code

Create an abstract class called Animal that inherits from ABC. It should have two abstract methods: speak() and move(). Then create a Dog class that inherits from Animal where speak() returns the string 'Woof!' and move() returns 'Runs on four legs'. Finally, create a dog and print both methods.

Loading editor...
Predict the ABC Error
Predict Output

What does this code print? Think carefully about which abstract methods are implemented and which are missing.

from abc import ABC, abstractmethod

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

    @abstractmethod
    def disconnect(self):
        pass

class SQLite(Database):
    def connect(self):
        return 'Connected'

try:
    db = SQLite()
except TypeError as e:
    print('Cannot create instance')
Loading editor...
Fix the Broken ABC
Fix the Bug

This code is supposed to define an abstract Logger class and a FileLogger that implements it. But it has bugs! Fix them so the output is:

Logging to file: Server started
Loading editor...
Abstract Property: Employee Types
Write Code

Create an abstract class Employee with an abstract property role and an abstract method salary(). Then create two subclasses:

  • Engineer where role returns 'Engineer' and salary() returns 95000
  • Manager where role returns 'Manager' and salary() returns 120000
  • Create one of each and print their info in the format: Role: salary

    Loading editor...
    Refactor to Use ABC
    Refactor

    The code below uses NotImplementedError to simulate abstract methods. Refactor it to use ABC and @abstractmethod instead. Keep the same output:

    Area: 50
    Area: 78.5

    Remove all NotImplementedError raises and use proper abstract methods.

    Loading editor...