PythonAbstract Base Classes

Abstract Base Classes

Some classes represent an incomplete idea on purpose. A generic "Shape" doesn't have a well-defined area — only a specific shape like a circle or a square does. Python's abc module lets you express that formally: mark a class as abstract, list the methods every concrete subclass must implement, and Python will refuse to create an instance of the class (or of any subclass that skips a required method) until those methods actually exist.

This buys you two things. First, it stops accidental instantiation of a class that was only ever meant to be a template. Second, it catches a missing implementation immediately, as soon as someone tries to use the incomplete subclass, rather than later when some unrelated piece of code calls a method that was never written.

ABC and @abstractmethod

To build an abstract base class, inherit from ABC (from the abc module) and decorate any required method with @abstractmethod. The method's body is never actually run for the abstract version — a pass statement or a docstring is enough, since its only purpose is to declare that subclasses must provide their own implementation.

Python
from abc import ABC, abstractmethod


class Shape(ABC):
    @abstractmethod
    def area(self):
        """Every concrete shape must implement this."""


class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius

    def area(self):
        return 3.14159 * self.radius ** 2


class Square(Shape):
    def __init__(self, side):
        self.side = side

    def area(self):
        return self.side ** 2


circle = Circle(3)
square = Square(4)
print(circle.area())
print(square.area())
28.27431
16

Both Circle and Square implement area() with logic appropriate to their own shape, and calling code doesn't need to know or care which concrete class it's holding.

Trying to Instantiate the Abstract Class Directly

Shape itself can never be instantiated, because it leaves area() unimplemented. Python enforces this at the moment you try to create an instance.

Python
shape = Shape()
TypeError: Can't instantiate abstract class Shape with abstract method area
A Subclass That Forgets to Implement the Method

Suppose a new subclass is defined but never gets around to implementing area(). Defining the class itself succeeds — Python doesn't check anything at definition time. The error only appears the moment you try to instantiate that incomplete subclass.

Python
class Triangle(Shape):
    def __init__(self, base, height):
        self.base = base
        self.height = height
    # area() was never written


t = Triangle(3, 4)
TypeError: Can't instantiate abstract class Triangle with abstract method area
Note
This is an important nuance: the `TypeError` is raised at instantiation time, not when `Triangle` is defined. The class body itself is syntactically fine and imports without error — the missing method is only discovered the moment someone tries to create a `Triangle()`. Keep this in mind if an incomplete subclass sits unused in your codebase for a while: nothing will complain until the first attempt to construct it.
Why Bother, Instead of Just Documenting the Requirement?
  • Prevents instantiating a class that represents an incomplete concept, like a generic Shape with no defined area.

  • Forces every subclass to implement the required methods, turning a "please remember to implement this" comment into something Python actually enforces.

  • Fails fast: a missing implementation surfaces as soon as the incomplete class is instantiated, not later when unrelated code eventually calls the missing method and hits an AttributeError deep in some other part of the program.