Script Valley
Python: Complete Language Course
Object-Oriented ProgrammingLesson 4.5

Python abstract classes and interfaces

abc module, ABC class, @abstractmethod, abstract properties, interface pattern, why abstract classes matter, NotImplementedError alternative

Abstract Classes

An abstract class defines a contract — methods that all subclasses must implement. You cannot instantiate an abstract class directly. Use the abc module.

from abc import ABC, abstractmethod

class Shape(ABC):
    @abstractmethod
    def area(self) -> float:
        """Return the area of the shape."""
        ...

    @abstractmethod
    def perimeter(self) -> float:
        ...

    def describe(self):
        print(f"Area: {self.area():.2f}, Perimeter: {self.perimeter():.2f}")

class Rectangle(Shape):
    def __init__(self, w, h):
        self.w = w
        self.h = h

    def area(self):
        return self.w * self.h

    def perimeter(self):
        return 2 * (self.w + self.h)

r = Rectangle(4, 5)
r.describe()  # Area: 20.00, Perimeter: 18.00

# Shape()  → TypeError: cannot instantiate abstract class

Why Use ABC

Without @abstractmethod, a subclass that forgets to implement a method will not raise an error until that method is actually called. With it, the error is raised immediately at instantiation — catching the bug earlier. Non-abstract methods in the base class are inherited normally.

Abstract classes enforce a contract at the class design level, not the runtime level. They document intent: subclasses of Shape must provide area and perimeter. This is especially valuable in team settings where multiple developers implement different subclasses independently. Python's abc module also supports abstract properties and abstract class methods. Protocols (from typing) are an alternative structural-typing approach — an object satisfies a Protocol if it has the required methods, without needing to explicitly inherit, following Python's duck-typing philosophy.