Start learning free

LESSON 186 OF 344 · OBJECT-ORIENTED PROGRAMMING

Interfaces in Python: Abstract Base Classes as Contracts

Lesson Read the full explanation

TL ; DR:

An interface is a pure contract — a list of methods that a class promises to implement, with no shared data and no shared code. Unlike inheritance ("is a"), interfaces express "can do".


from abc import ABC, abstractmethod
# Python uses ABCs in place of true interfaces:
class Speaker(ABC):
    @abstractmethod
    def speak(self): pass
class Dog(Speaker):
    def speak(self):
        print("Woof")


Full lesson:

An interface defines what a class can do, not how it does it or what it is. A Truck, a Robot, and a Drone aren't the same kind of thing — but they can all Move(). You'd put Move() in a Movable interface and have each one implement it.

Interface vs abstract class

Abstract classInterface
Has fieldsYesUsually no
Has method bodiesYes (some)No (or default impls only)
Multiple "inheritance"Usually noYes — a class can implement many interfaces
Models"is a""can do"

A class inherits from at most one parent class but can implement many interfaces. That's why interfaces are the right tool for cross-cutting capabilities like Comparable, Serializable, Iterable, etc.

The language landscape

  • C# / Java — first-class interface keyword. C# uses : for both inheritance and implementation; Java uses extends for inheritance and implements for interfaces.
  • Python — no separate interface; abstract base classes (ABCs) with all-abstract methods serve the same role.
  • JavaScript — no interface keyword in plain JS (TypeScript has it). The convention is a stub class.
  • C++ — a class with only pure-virtual methods is an interface. Multiple inheritance lets a class implement several.

Your task

The Speaker interface (or interface-like base) is already declared. Create a Dog class that implements it, with a speak() method that prints "Woof".

Expected output:

Woof
STEP 1 OF 2
    Ctrl + Enter to check

    PYTHON · OBJECT-ORIENTED PROGRAMMING

    Interfaces in Python, explained

    What an interface is

    An interface is a contract: a list of methods that a class promises to provide. It says what an object can do, not how it does it and not what kind of thing it is. A Truck, a Robot and a Drone are unrelated, yet all three can move. A Movable contract with one method, move(), lets code work with any of them without knowing which one it holds.

    Inheritance models "is a". A Dog is an Animal. An interface models "can do". A Dog can speak, and so can a parrot, a robot and a doorbell.

    An interface carries no shared data and no shared code, only the list of promised methods. An abstract class can hold fields and ready-made methods too, and a class usually extends only one parent. A class can promise many interfaces at once, which suits capabilities that cut across a design, such as "can be compared" or "can be saved".

    Interfaces in Python: abstract base classes

    Python has no interface keyword. Its tool for the job is the abstract base class (ABC) from the abc module. You inherit from ABC and mark each promised method with @abstractmethod. If every method in the class is abstract and the class holds no data, it plays the role of an interface.

    from abc import ABC, abstractmethod
    
    class Speaker(ABC):
        @abstractmethod
        def speak(self): pass
    

    The body of an abstract method is usually just pass. Subclasses supply the real behaviour.

    What Python enforces

    You can't create an object from a class that still has abstract methods. Python checks this when you call the class:

    class Cat(Speaker):
        pass
    
    Cat()
    

    This raises TypeError, and the message reads Can't instantiate abstract class Cat without an implementation for abstract method 'speak'. The same happens for Speaker() itself. The error appears when you try to build the object, not when the class is defined. A subclass that overrides every abstract method can be instantiated normally.

    Implementing several interfaces

    Python allows multiple inheritance, so a class lists each contract in its parentheses:

    class Mover(ABC):
        @abstractmethod
        def move(self): pass
    
    class Robot(Speaker, Mover):
        def speak(self): print("Beep")
        def move(self): print("Rolling")
    

    If Robot defined only one of the two methods, Robot() would raise the same TypeError, naming the missing one.

    Duck typing and what the ABC adds

    Python code often skips contracts altogether. A function that calls thing.speak() works with any object that has a speak method, whether or not it inherits from Speaker. This is duck typing: if it speaks like a speaker, it is one for practical purposes.

    An ABC adds a guarantee on top. It fails early, at construction, when a method is missing, instead of later with an AttributeError in the middle of a program. It also makes the contract visible in the code, and it allows isinstance(obj, Speaker) checks. A class that has a speak method but doesn't inherit from Speaker fails that isinstance test.

    The exercise

    The starter code already declares Speaker and ends with these two lines, which create a Dog and ask it to speak:

    rex = Dog()
    rex.speak()
    

    There is no Dog yet, so the program fails with a NameError. The lesson has two steps:

    1. Declare Dog and list Speaker in parentheses. That makes Dog a subclass of the contract. On its own, this class would still be abstract, because speak is not implemented.
    2. Define speak with self inside Dog. It overrides the abstract method and prints Woof. Once every abstract method is overridden, Dog() works.

    The finished program:

    from abc import ABC, abstractmethod
    
    class Speaker(ABC):
        @abstractmethod
        def speak(self): pass
    
    class Dog(Speaker):
        def speak(self):
            print("Woof")
    
    rex = Dog()
    rex.speak()
    

    Running it prints:

    Woof
    

    Common mistakes

    • Misspelling the method name. A method called Speak or speek doesn't override speak, so the abstract method is still missing and Dog() raises TypeError. Python names are case-sensitive.
    • Forgetting self. def speak(): accepts no arguments, but calling rex.speak() passes the object automatically. The result is a TypeError about the number of arguments.
    • Returning instead of printing. The lesson expects the text on the output. A method with return "Woof" would run without printing anything.
    • Forgetting to inherit from ABC. @abstractmethod is only enforced when the class has ABC as a base (or uses ABCMeta). Without it, Speaker() would be creatable and the contract would be a suggestion.
    • Putting Dog after the code that uses it. Python runs top to bottom, so the class must be defined before Dog() is called.

    Key takeaways

    • An interface lists what a class can do; inheritance says what a class is.
    • Python expresses interfaces with ABC and @abstractmethod.
    • A class with unimplemented abstract methods can't be instantiated: Python raises TypeError at the call.
    • A class can inherit several ABCs and must implement all their abstract methods.
    • Duck typing works without any contract; ABCs add early errors and isinstance checks.
    Keep going with PythonAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free