Abstract Base Classes (abc)

An abstract base class is a class you can't instantiate directly — it declares methods that every subclass must implement, and Python enforces that contract by raising a TypeError if a subclass leaves any of them out.

Learn Abstract Base Classes (abc) in our free Python course — an interactive lesson with runnable examples, a practice exercise and a quick reference.

Part of the free Python course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

ABCs let you design a clear interface up front — "every payment method needs a pay() and a refund()" — and catch incomplete classes the moment someone tries to use them, instead of much later when the missing method blows up.

Inherit from abc.ABC and decorate the methods you want to require with @abstractmethod . The base class becomes a contract : it describes what subclasses must do, without saying how .

The ABC base flips on the machinery; each @abstractmethod adds one more requirement subclasses must satisfy.

Here's the payoff. You cannot create an instance of the ABC itself, and you cannot create an instance of any subclass that forgot to implement an abstract method. Python catches it instantly:

Without the ABC, BrokenWallet() would succeed and only explode later when something called .refund() . The ABC moves the failure to the earliest, clearest possible moment.

An ABC isn't all-or-nothing. It can also provide concrete methods that build on the abstract ones — giving subclasses shared behavior for free while still demanding they fill in the gaps.

Sometimes a class already behaves like your interface but you can't (or don't want to) make it inherit from the ABC — maybe it's third-party code. .register() tells Python "treat this class as a subclass" for isinstance / issubclass checks, without changing its inheritance:

collections.abc — interfaces that already exist

The standard library ships ABCs for container behaviors. Anything with a __len__ is a Sized ; anything iterable is an Iterable — no inheritance required, because these ABCs check for the methods:

A Protocol matches any class with the right methods — no inheritance, checked by type checkers (structural typing). An ABC requires explicit inheritance or registration (nominal typing) but enforces the contract at runtime:

Complete the code so Dog properly implements the Animal interface. Replace each ___ with the correct token, then run it.

✅ Inherit from ABC (or set metaclass=ABCMeta ) — @abstractmethod alone does nothing without it.

✅ Match the abstract method name exactly. The ABC only counts a requirement as met when the names line up.

✅ Only register classes that genuinely satisfy the interface — registration is an unchecked promise.

Build an abstract Notifier with an abstract send(message) and a concrete announce() that prefixes the channel name. Then create two concrete notifiers.

Lesson complete — you can design enforced interfaces!

You can declare an interface with abc.ABC and @abstractmethod , rely on the TypeError to catch incomplete subclasses, mix abstract and concrete methods, adopt virtual subclasses with .register() , and choose between an ABC and a Protocol . That's the foundation of robust object-oriented design.

🚀 Up next: Properties & Descriptors — turn methods into smart, validated attributes.

Practice quiz

How do you make a class abstract so it can't be instantiated directly?

  • Add @staticmethod to it
  • Use the @abstract decorator on the class
  • Inherit from abc.ABC
  • Set abstract = True

Answer: Inherit from abc.ABC. A class becomes abstract by inheriting from abc.ABC (or using metaclass=ABCMeta).

What happens when you try to instantiate a subclass that hasn't implemented an @abstractmethod?

  • Python raises a TypeError
  • It works but the method returns None
  • It raises NotImplementedError
  • Python prints a warning and continues

Answer: Python raises a TypeError. Instantiating a class with unimplemented abstract methods raises TypeError immediately.

What does @abstractmethod do on its own, in a plain class that does NOT inherit from ABC?

  • Makes the class abstract anyway
  • Raises a SyntaxError
  • Automatically adds an __enter__ method
  • Nothing — without ABC there is no enforcement

Answer: Nothing — without ABC there is no enforcement. @abstractmethod alone does nothing; the class must inherit from ABC for enforcement.

Can an ABC contain concrete (fully implemented) methods alongside abstract ones?

  • No, ABCs may only contain abstract methods
  • Yes, and subclasses inherit the concrete methods as-is
  • Yes, but subclasses must re-implement them all
  • Only if they are static methods

Answer: Yes, and subclasses inherit the concrete methods as-is. ABCs can mix abstract and concrete methods; subclasses inherit concrete ones (the template-method pattern).

What does Drawable.register(Sprite) do?

  • Makes Sprite a virtual subclass for isinstance/issubclass checks
  • Verifies Sprite has all required methods
  • Copies Drawable's concrete methods into Sprite
  • Raises an error if Sprite lacks draw()

Answer: Makes Sprite a virtual subclass for isinstance/issubclass checks. register() makes a class a virtual subclass for isinstance/issubclass without checking or inheriting methods.

Does register() verify that the registered class actually has the required methods?

  • Yes, it checks every abstract method
  • Only in Python 3.11+
  • No, registration is an unchecked promise
  • Only for collections.abc classes

Answer: No, registration is an unchecked promise. Registration is a promise, not a check — Python trusts you that the class satisfies the interface.

Which typing approach matches any class with the right methods, with NO inheritance required?

  • abc.ABC
  • typing.Protocol (structural typing)
  • ABCMeta
  • collections.abc.Sized

Answer: typing.Protocol (structural typing). typing.Protocol uses structural typing — any class with the right methods matches without inheriting.

What kind of typing does an ABC use?

  • Structural typing
  • Duck typing only
  • No typing at all
  • Nominal typing — needs explicit inheritance or registration

Answer: Nominal typing — needs explicit inheritance or registration. ABCs use nominal typing: a class is a subtype only if it inherits from or is registered with the ABC.

Given a class Box with only a __len__ method, what does isinstance(Box(), Sized) return?

  • False
  • True
  • It raises TypeError
  • None

Answer: True. collections.abc.Sized matches anything with __len__, so isinstance returns True.

When should you reach for an ABC instead of a Protocol?

  • When you want to avoid any inheritance
  • Only for static type checking
  • When you want runtime enforcement and shared base logic
  • When the class is third-party code you can't modify

Answer: When you want runtime enforcement and shared base logic. Choose an ABC for runtime enforcement, shared base logic, or an explicit hierarchy.