Codectionary / Developer documentation / Python

Abstract Base Classes

Abstract base classes, provided by the abc module, let you define a common interface that subclasses are required to implement. A class inheriting from ABC and using the @abstractmethod decorator cannot be instantiated directly - any concrete subclass must override every abstract method, or it can't be instantiated either. This is useful for enforcing a consistent interface across multiple related classes, similar to interfaces in other languages.

Syntax

from abc import ABC, abstractmethod

Examples

Basic Abstract Class

Defining a base class that cannot be instantiated on its own.

from abc import ABC, abstractmethod

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

# shape = Shape()  # would raise TypeError - can't instantiate an abstract class

Enforcing Implementation in Subclasses

Every subclass must implement the abstract method or it cannot be instantiated either.

from abc import ABC, abstractmethod

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

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

shapes = [Circle(5), Square(4)]
for shape in shapes:
    print(f"{type(shape).__name__}: {shape.area():.2f}")

Abstract Class with Concrete Methods

Abstract classes can also include regular, already-implemented methods that subclasses inherit as-is.

from abc import ABC, abstractmethod

class Employee(ABC):
    def __init__(self, name):
        self.name = name

    @abstractmethod
    def calculate_pay(self):
        pass

    def display(self):  # concrete method, shared by all subclasses
        print(f"{self.name}: ${self.calculate_pay():.2f}")

class SalariedEmployee(Employee):
    def __init__(self, name, salary):
        super().__init__(name)
        self.salary = salary

    def calculate_pay(self):
        return self.salary / 12

emp = SalariedEmployee("Fola", 48000)
emp.display()  # Fola: $4000.00

Best practices

  • Use abstract base classes to guarantee that every subclass implements a required set of methods, catching missing implementations early
  • Combine abstract methods with regular concrete methods on the same base class for shared functionality plus enforced customization points
  • Remember you cannot instantiate a class that still has unimplemented abstract methods - Python raises a TypeError immediately
  • Reach for ABCs when designing a plugin-style system or a family of related classes that must all support the same interface

At a glance

Purpose
Scripting and general-purpose applications
File extension
.py
Runs in
Python interpreter
Usually used with
Python standard library and packages

Specifications & further reading

Related Python documentation

class
The class keyword defines a blueprint for creating objects in Python. Classes are the foundation of Object-Oriented Programming (OOP), allowing you to bundle data (attributes) and functionality (methods) together. A class defines what attributes an object will have and what operations can be performed on it. Think of a class as a template or a factory for creating objects with similar characteristics.
Inheritance & super()
Inheritance lets a class (the child or subclass) reuse and extend the attributes and methods of another class (the parent or superclass), written as class Child(Parent). The built-in super() function gives access to the parent class's methods from within the child, most commonly used to call the parent's __init__ so the child doesn't have to duplicate its setup logic. Python also supports multiple inheritance, where a class inherits from more than one parent.
Magic (Dunder) Methods
Magic methods, also called dunder (double underscore) methods, let your custom classes hook into Python's built-in syntax and behavior. __init__ runs on object creation, __str__ controls how an object is displayed with print(), __eq__ and __lt__ control comparisons, __len__ controls the len() function, and __add__ lets objects respond to the + operator. Implementing these makes your custom classes feel like natural, first-class Python types.
@property
The @property decorator lets you define a method that can be accessed like a plain attribute, without parentheses. This is useful for computed values that should look like simple attributes, and for adding validation logic that runs whenever an attribute is set, via a matching @x.setter. Properties let you start with simple public attributes and later add logic without breaking any code that uses the class.