OSPython.016: Abstraction and Abstract Base Classes Basics

Minimal black and neon-green illustration representing Python abstraction and abstract base classes.

Abstraction lets Python programs expose the behavior a caller needs while hiding unnecessary implementation details. Abstract base classes can go one step further by defining a contract that subclasses must implement.

This lesson follows OSPython.015: Encapsulation Basics. The previous lessons covered inheritance, polymorphism, and encapsulation. Abstraction completes this introductory pass through the four major object-oriented design principles.

What abstraction means

Abstraction means presenting a useful interface while keeping implementation details behind that interface. A technician using a monitoring object may only need methods such as read_temperature() and health_status(). The caller should not need to know every parsing, protocol, retry, or validation step behind those methods.

class TemperatureSensor:
    def read_temperature(self):
        # Internal device communication is hidden here.
        return 67.4

sensor = TemperatureSensor()
print(sensor.read_temperature())

The method name gives the caller a simple interface. The implementation can change later without forcing every caller to understand the internal details.

Video 1: Abstract base classes

Real Python explains why abstract base classes are useful and how they establish a consistent interface for subclasses.

Python’s abc module

Python’s standard-library abc module provides tools for defining abstract base classes, commonly called ABCs. The two beginner-level pieces to recognize are ABC and @abstractmethod.

from abc import ABC, abstractmethod

class PowerDevice(ABC):
    @abstractmethod
    def status(self):
        pass

PowerDevice describes a required capability. It says that concrete subclasses must provide a status() implementation before they can be instantiated normally.

Concrete subclasses

from abc import ABC, abstractmethod

class PowerDevice(ABC):
    @abstractmethod
    def status(self):
        pass

class PDU(PowerDevice):
    def status(self):
        return "PDU online"

class UPS(PowerDevice):
    def status(self):
        return "UPS online"

pdu = PDU()
ups = UPS()

print(pdu.status())
print(ups.status())

Both concrete classes satisfy the contract by implementing status(). The caller can work with either device through the same high-level operation.

What happens if a subclass is incomplete?

class Transformer(PowerDevice):
    pass

unit = Transformer()

Because Transformer does not implement the required abstract method, attempting to instantiate it raises a TypeError. That is useful when a project needs a formal class contract rather than an informal naming convention.

Video 2: Abstraction as an OOP principle

GeeksforGeeks School gives a concise explanation of abstraction and the idea of exposing essential behavior while hiding implementation detail.

Abstract methods and concrete methods can coexist

An ABC does not have to contain only empty abstract methods. It can provide shared concrete behavior while requiring subclasses to supply specific pieces.

from abc import ABC, abstractmethod

class Monitor(ABC):
    def log_start(self):
        print("Monitoring started")

    @abstractmethod
    def read_value(self):
        pass

class TemperatureMonitor(Monitor):
    def read_value(self):
        return 68.2

monitor = TemperatureMonitor()
monitor.log_start()
print(monitor.read_value())

log_start() is concrete shared behavior. read_value() is the required extension point.

Abstraction vs. encapsulation

The concepts are related but not identical. Abstraction focuses on what useful interface should be exposed. Encapsulation focuses on organizing state and behavior together and controlling how internal state is accessed or changed.

# Abstraction question:
# "What operations should every sensor provide?"

# Encapsulation question:
# "How should the sensor protect and validate its internal state?"

Abstraction and polymorphism

ABCs also work naturally with polymorphism. Different concrete classes can satisfy the same abstract contract with different implementations.

devices = [PDU(), UPS()]

for device in devices:
    print(device.status())

The loop depends on the common interface instead of the internal details of each device class.

Video 3: Python abstract classes in code

Bro Code’s Python course series demonstrates abstract classes and required subclass behavior with runnable Python examples.

A data-center example

from abc import ABC, abstractmethod

class CoolingSystem(ABC):
    @abstractmethod
    def supply_temperature(self):
        pass

    @abstractmethod
    def healthy(self):
        pass

class AirCooling(CoolingSystem):
    def supply_temperature(self):
        return 22.5

    def healthy(self):
        return True

class ImmersionCooling(CoolingSystem):
    def supply_temperature(self):
        return 35.0

    def healthy(self):
        return True

def print_cooling_status(system):
    print(f"Supply: {system.supply_temperature()} C")
    print(f"Healthy: {system.healthy()}")

print_cooling_status(AirCooling())
print_cooling_status(ImmersionCooling())

The reporting function does not need to know how an air system or immersion system gathers its measurements. It depends on the abstraction: every supported cooling system supplies the same required operations.

When an ABC is useful

  • Several related classes must provide the same operations.
  • You want Python to reject incomplete subclasses at instantiation time.
  • You need a clear extension contract for a framework or internal API.
  • You have shared base behavior plus required subclass-specific behavior.

Do not add an ABC merely because a project contains multiple classes. Python also supports ordinary inheritance, duck typing, and typing protocols. Use the simplest design that expresses the requirement clearly.

Common beginner mistakes

  • Forgetting to inherit from ABC when intending to create an ABC using the common modern pattern.
  • Forgetting the @abstractmethod decorator.
  • Trying to instantiate an abstract class that still has unimplemented abstract methods.
  • Assuming abstraction and encapsulation mean exactly the same thing.
  • Creating an elaborate inheritance hierarchy when a simple class or function would be clearer.

Practice

  1. Create an ABC named Sensor.
  2. Add an abstract method named read().
  3. Create TemperatureSensor and PowerSensor subclasses.
  4. Implement read() differently in each subclass.
  5. Place both objects in a list and call read() in a loop.
  6. Create an intentionally incomplete subclass and observe the error when you try to instantiate it.

Knowledge check

Question: What does abstraction emphasize?
Answer: exposing the essential interface while hiding unnecessary implementation details.

Question: Which standard-library module supports abstract base classes?
Answer: abc.

Question: What decorator marks a required abstract method?
Answer: @abstractmethod.

Question: Can a class with an unimplemented abstract method normally be instantiated?
Answer: no; Python raises a TypeError.

Previous Python lessons

OSPython.015: Encapsulation Basics

OSPython.014: Polymorphism Basics

OSPython.013: Inheritance Basics

Reference

Python’s standard-library documentation for abc is available in the Python documentation. Real Python also provides detailed ABC examples and interface discussions.

Key takeaway

Abstraction helps code depend on clear capabilities rather than internal implementation details. Python’s abstract base classes let you formalize that idea when related subclasses must satisfy a shared contract.

2 responses to “OSPython.016: Abstraction and Abstract Base Classes Basics”

  1. […] disappear. It makes them more important when a developer has to review what the agent changed. Our OSPython lesson on abstraction and abstract base classes teaches a concept that carries directly into game architecture: define a common contract while […]

    Like

  2. […] same fundamentals behind our lesson on abstraction show up here at a lower level. The game sees an input-event abstraction; underneath it, […]

    Like

Leave a comment