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:
- Declare
Dogand listSpeakerin parentheses. That makesDoga subclass of the contract. On its own, this class would still be abstract, becausespeakis not implemented. - Define
speakwithselfinsideDog. It overrides the abstract method and printsWoof. 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
Speakorspeekdoesn't overridespeak, so the abstract method is still missing andDog()raisesTypeError. Python names are case-sensitive. - Forgetting
self.def speak():accepts no arguments, but callingrex.speak()passes the object automatically. The result is aTypeErrorabout 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.@abstractmethodis only enforced when the class hasABCas a base (or usesABCMeta). Without it,Speaker()would be creatable and the contract would be a suggestion. - Putting
Dogafter the code that uses it. Python runs top to bottom, so the class must be defined beforeDog()is called.
Key takeaways
- An interface lists what a class can do; inheritance says what a class is.
- Python expresses interfaces with
ABCand@abstractmethod. - A class with unimplemented abstract methods can't be instantiated: Python raises
TypeErrorat 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
isinstancechecks.