Difference between abstract class and interface in Python
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Python does not have a built-in interface keyword like Java or C#, so the comparison is slightly different from many other languages. In practice, the closest tools are abstract base classes from abc and structural protocols from typing. The useful distinction is whether you want shared implementation and nominal inheritance, or you want to describe a required shape without caring about the inheritance tree.
Abstract Base Classes Give You Shared Design and Shared Code
An abstract base class, usually built with ABC and @abstractmethod, defines a contract that subclasses must implement. It can also include concrete methods, shared state, and ordinary helper logic.
This is useful when subclasses should share implementation details or common state as well as a required API.
Protocols Act More Like Interfaces
If you want interface-like behavior in modern Python, typing.Protocol is the closer match. A protocol says, in effect, “anything with these methods and attributes is acceptable,” even if it never inherits from the protocol directly.
ConsoleWriter does not inherit from Writer, but type checkers can still treat it as compatible because it has the required method. That is structural typing, and it is much closer to the spirit of interfaces.
The Practical Difference
A useful rule is:
- use an abstract base class when you want a family of related classes with shared behavior or shared state
- use a protocol when you care only about what an object can do, not what it inherits from
This distinction matches Python’s broader design style. Python often prefers behavior-based compatibility over strict inheritance hierarchies.
Python Also Has Duck Typing
It is worth remembering that many Python programs do not need either tool. Plain duck typing often works well:
If the object has a working write method, the function succeeds. Abstract base classes and protocols become most valuable when you want stronger API documentation, runtime enforcement, or static type-checking support.
When an Abstract Base Class Is Better
Use an abstract base class when:
- subclasses need shared code
- subclasses should inherit common state
- you want explicit nominal membership in a class family
- runtime checks such as
isinstanceagainst the base class are meaningful to your design
That is why frameworks often use ABCs for pluggable backends or adapters that share helper methods.
When a Protocol Is Better
Use a protocol when:
- unrelated classes should satisfy the same contract
- inheritance would be artificial or inconvenient
- you want static typing to validate “has these methods” behavior
- you do not need shared implementation
That makes protocols especially good for service objects, serializers, loggers, repositories, and other behavior-oriented abstractions.
Common Pitfalls
- Assuming Python interfaces work exactly like Java interfaces.
- Using an abstract base class when there is no shared behavior and only a behavioral contract is needed.
- Forcing inheritance into a design that would be cleaner with a protocol or plain duck typing.
- Expecting protocols to provide runtime behavior or shared implementation.
- Forgetting that a
readonly-style interface concept does not exist separately from Python’s normal attribute and method model.
Summary
- Python’s abstract base classes and protocols solve different abstraction problems.
- Use
ABCwhen you want shared implementation and an explicit inheritance family. - Use
Protocolwhen you want interface-like structural typing. - Plain duck typing is still a valid and often simple option in Python.
- The best choice depends on whether you care about shared code, explicit inheritance, or just required behavior.

