Abstract Classes
On this page
Require an OperationAttempt Abstract InstantiationShare Concrete BehaviorRequire a PropertyCheck Whether a Class Is ConcreteCoding Challenge: Abstract Class for a Notification SystemAn abstract base class can combine required operations with reusable behavior. A class with unresolved abstract members cannot be instantiated.
UML italicizes the abstract class and required operation. The hollow triangle shows that Dog inherits from Animal and supplies sound().
Require an Operation
from abc import ABC, abstractmethod
class Animal(ABC):
@abstractmethod
def sound(self):
passDefines Animal; no visible output.
class Dog(Animal):
def sound(self):
return "Bark"
dog = Dog()
print(dog.sound())Output
Bark
Dog supplies sound, so it is concrete and can be instantiated.
Attempt Abstract Instantiation
from abc import ABC, abstractmethod
class Animal(ABC):
@abstractmethod
def make_sound(self):
pass
try:
animal = Animal()
except TypeError:
print("TypeError: Animal still has an abstract method")Output
TypeError: Animal still has an abstract method
The intentional TypeError is caught. No Animal instance is created. An abstract method may contain implementation code and still require an override.
Share Concrete Behavior
from abc import ABC, abstractmethod
class Animal(ABC):
@abstractmethod
def make_sound(self):
pass
def move(self):
return "The animal moves."Defines Animal; no visible output.
class Dog(Animal):
def make_sound(self):
return "Bark"
dog = Dog()
print(dog.move()) # inherited concrete method
print(dog.make_sound()) # Dog's implementationOutput
The animal moves.
Bark
Dog inherits move and implements make_sound.
Require a Property
Place @property above @abstractmethod, so the abstract marker applies to the getter.
The italic class name marks the abstract base; /species is a derived, read-only UML attribute. In Python the abstract requirement is implemented by a property getter, supplied by Dog.
from abc import ABC, abstractmethod
class Animal(ABC):
@property
@abstractmethod
def species(self):
passDefines Animal; no visible output.
class Dog(Animal):
@property
def species(self):
return "Canine"
dog = Dog()
print(dog.species)Output
Canine
The property is read as dog.species, without parentheses.
Check Whether a Class Is Concrete
from abc import ABC, abstractmethod
class Animal(ABC):
@abstractmethod
def make_sound(self):
pass
try:
animal = Animal()
except TypeError:
print("TypeError: Animal still has an abstract method")Output
TypeError: Animal still has an abstract method
An ABC with no unresolved abstract members can be instantiated. Abstract checks enforce required names, not the correctness of their behavior.
Coding Challenge: Abstract Class for a Notification System
Define NotificationChannel with a required send(target, message) method, a required read-only name property and a shared logging method. Implement Email and SMS subclasses. Each send must print its simulated action, then call the shared logger. Send the same message through both.
Target output for your solution
[Email] Sending to user@example.com: System update at 18:00
[LOG] Email delivered: System update at 18:00
[SMS] Sending to +4912345678: System update at 18:00
[LOG] SMS delivered: System update at 18:00
These are console simulations, not actual email or SMS delivery. Confirm that the abstract base cannot be instantiated.
The examples so far use one base class. Multiple inheritance introduces a class with more than one base and explains how Python resolves its methods.