Abstract Classes: Define Clear Contracts for Subclasses

Introduction

In this chapter, you will learn abstract classes in Python and why they matter in object-oriented design. Abstract classes let you define a shared structure and force child classes to implement required methods. This helps you build consistent, extensible, and maintainable code.

Prerequisites

  • Python 3.10+ installed
  • Basic understanding of classes, inheritance, and method overriding
  • Ability to run .py files in terminal or IDE

What Is an Abstract Class

An abstract class is a class that cannot be instantiated directly.

It is used to:

  • define shared behavior
  • define required method contracts
  • guide child class implementation

In Python, abstract classes are commonly built with:

  • ABC from abc module
  • @abstractmethod decorator

1) Basic Abstract Class Syntax

Use ABC as base class and mark required methods with @abstractmethod.

python
# Import abstract class tools
from abc import ABC, abstractmethod
 
 
# Define abstract class
class Animal(ABC):
    @abstractmethod
    def make_sound(self):
        pass

Animal cannot be created directly because make_sound() is abstract.

2) Implement Abstract Methods in Child Classes

Child classes must implement all abstract methods.

python
# Import abstract class tools
from abc import ABC, abstractmethod
 
 
# Abstract class
class Animal(ABC):
    @abstractmethod
    def make_sound(self):
        pass
 
 
# Child class implementation
class Dog(Animal):
    def make_sound(self):
        print("Woof")
 
 
# Child class implementation
class Cat(Animal):
    def make_sound(self):
        print("Meow")
 
 
# Create objects from concrete classes
dog = Dog()
cat = Cat()
dog.make_sound()
cat.make_sound()

If a child class does not implement required methods, it also cannot be instantiated.

3) Abstract Class with Shared Concrete Methods

Abstract classes can include normal implemented methods too.

python
# Import abstract class tools
from abc import ABC, abstractmethod
 
 
# Abstract base class
class Payment(ABC):
    @abstractmethod
    def pay(self, amount):
        pass
 
    def validate_amount(self, amount):
        return amount > 0
 
 
# Concrete class
class CreditCardPayment(Payment):
    def pay(self, amount):
        if self.validate_amount(amount):
            print(f"Paid {amount} by credit card.")
        else:
            print("Invalid payment amount.")

This pattern is practical: shared logic in base, custom behavior in children.

Tip

Design Hint

Use abstract classes when multiple child classes should follow the same interface contract.

4) Real Mini Example: Learning Platform Content

This example models different lesson content types.

python
# Import abstract class tools
from abc import ABC, abstractmethod
 
 
# Abstract content class
class LearningContent(ABC):
    def __init__(self, title):
        self.title = title
 
    @abstractmethod
    def render(self):
        pass
 
 
# Video content class
class VideoLesson(LearningContent):
    def render(self):
        print(f"Playing video lesson: {self.title}")
 
 
# Quiz content class
class QuizLesson(LearningContent):
    def render(self):
        print(f"Opening quiz lesson: {self.title}")
 
 
# Use polymorphism
contents = [
    VideoLesson("Python Functions"),
    QuizLesson("Function Practice Quiz")
]
 
for item in contents:
    item.render()

This design keeps behavior consistent while allowing different implementations.

5) Why Abstract Classes Matter

Abstract classes help you:

  • avoid incomplete subclass designs
  • enforce architecture rules
  • improve team collaboration through clear contracts
  • support polymorphism safely

Compared with plain inheritance, abstract classes are stricter and more intentional.

Warning

Do not use abstract classes for tiny one-off scripts.
They are most helpful when your project has multiple related subclasses.

Common Beginner Mistakes

Mistake 1: Instantiating Abstract Class Directly

Animal() fails when abstract methods are not implemented.

Mistake 2: Forgetting to Implement All Abstract Methods

If one method is missing, subclass instantiation fails.

Mistake 3: Overusing Abstract Classes

For very small projects, simple classes or functions may be enough.

Surprise Practice Challenge

Build an abstract notification system:

  1. Abstract class Notifier with abstract method send(message)
  2. Child class EmailNotifier
  3. Child class SMSNotifier
  4. Put objects in a list and call send() for each
  5. Add one shared concrete method in Notifier (for example logging)

If you finish this, you can design contract-based OOP structures used in real systems.

FAQ

What is the difference between normal base class and abstract class?

A normal base class can be instantiated; an abstract class cannot and is used to enforce required methods.

Do abstract classes improve runtime speed?

Not the main goal. They improve code structure, consistency, and maintainability.

Can abstract classes contain implemented methods?

Yes. They can include both abstract and concrete methods.

Should I use abstract class or interface-style design?

In Python, abstract classes from abc are a common way to model interface-like contracts.