Python abstraction with abstract classes
Specify required behavior while leaving implementation to subclasses.
Python
from abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
def area(self):
pass
class Rectangle(Shape):
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
shape = Rectangle(3, 4)
print(shape.area())
assert Rectangle(0, 4).area() == 0Output
12
Explanation
An abstract base class can declare methods that concrete subclasses must implement. It describes what callers may request without prescribing one implementation.
Shape requires area. Rectangle supplies it using width and height. Instantiating Shape itself would raise TypeError because its abstract method is not implemented.
Explore the dry run
Guided walkthroughReady
1
from abc import ABC, abstractmethod2
3
class Shape(ABC):4
@abstractmethod5
def area(self):6
pass7
8
class Rectangle(Shape):9
def __init__(self, width, height):10
self.width = width11
self.height = height12
def area(self):13
return self.width * self.height14
15
shape = Rectangle(3, 4)16
print(shape.area())17
assert Rectangle(0, 4).area() == 0Follow the example
Start to inspect the source, values, and output. These prepared steps explain the published sample; grouped loop steps describe multiple iterations.
View the complete dry-run table
| Step / line | What happens | State after step | Output so far |
|---|---|---|---|
| Define the abstract contract. | — | — | |
| Create a concrete instance. | width = 3, height = 4 | — | |
| Compute the rectangle implementation of area. | return = 12 | — | |
| Print the result. | return = 12 | 12 | |
| Check a zero-width rectangle. | return = 12 | 12 |
Cost and common mistakes
O(1) arithmetic operations and O(1) object state.
- This example assumes nonnegative numeric dimensions.
- An abstract base class is useful for an explicit contract, but is not required for all Python polymorphism.
Try it yourself
Implement Square with one side and an area method.
Reveal answer and reasoning
Store side in __init__, return side * side, and check that Square(5).area() is 25.