Course Progress74%
🍎 Python Advanced Python Topic 74 / 100
⏳ 8 min read

Abstract Classes

Define interfaces with ABC and @abstractmethod — guarantee that every child class implements the methods it promises to.

"An abstract class is a contract. It says: every class that inherits from me MUST implement these methods. No exceptions."

— ShurAI

The Problem: Forgetting to Implement Methods

When you build an inheritance hierarchy, a child class might forget to implement a critical method. You only find out when it crashes at runtime — too late:

python — silent bug without ABC
class Shape:
    def area(self):
        pass   # child SHOULD override this, but nothing forces it

class Square(Shape):
    pass   # forgot area() — Python happily creates it

s = Square()
s.area()   # returns None silently — problem found too late

ABC — Enforcing the Contract

Inherit from ABC and mark required methods with @abstractmethod. Python will refuse to create any class that doesn’t implement all abstract methods:

python
from abc import ABC, abstractmethod

class Shape(ABC):               # inherit from ABC
    @abstractmethod
    def area(self) -> float:     # every child MUST implement this
        pass

    @abstractmethod
    def perimeter(self) -> float:
        pass

# Trying to instantiate Shape directly raises TypeError:
# Shape()  →  TypeError: Can't instantiate abstract class Shape

# A child that forgets area() also raises TypeError at creation:
class BadSquare(Shape):
    def perimeter(self): return 0
# BadSquare()  →  TypeError: Can't instantiate — area() not implemented
Abstract class as a contract
Shape (ABC)
@abstractmethod: area(), perimeter()
↓ must implement both methods
Circle ✅
Rectangle ✅
BadSquare ❌

Implementing the Contract

python
import math

class Circle(Shape):
    def __init__(self, radius: float):
        self.radius = radius

    def area(self) -> float:
        return math.pi * self.radius ** 2

    def perimeter(self) -> float:
        return 2 * math.pi * self.radius


class Rectangle(Shape):
    def __init__(self, w: float, h: float):
        self.w, self.h = w, h

    def area(self) -> float:
        return self.w * self.h

    def perimeter(self) -> float:
        return 2 * (self.w + self.h)

shapes = [Circle(5), Rectangle(4, 6)]
for s in shapes:
    print(f"{s.__class__.__name__}: area={s.area():.2f}, perimeter={s.perimeter():.2f}")
output
Circle: area=78.54, perimeter=31.42
Rectangle: area=24.00, perimeter=20.00

Real Example — Payment Gateway Interface

python
from abc import ABC, abstractmethod

class PaymentGateway(ABC):
    @abstractmethod
    def charge(self, amount: float) -> bool: pass

    @abstractmethod
    def refund(self, amount: float) -> bool: pass

    def receipt(self, amount: float):
        print(f"Receipt: {self.__class__.__name__} charged {amount}")

class StripeGateway(PaymentGateway):
    def charge(self, amount):
        print(f"Stripe: charging {amount}")
        return True
    def refund(self, amount):
        print(f"Stripe: refunding {amount}")
        return True

class RazorpayGateway(PaymentGateway):
    def charge(self, amount):
        print(f"Razorpay: charging {amount}")
        return True
    def refund(self, amount):
        print(f"Razorpay: refunding {amount}")
        return True

for gw in [StripeGateway(), RazorpayGateway()]:
    gw.charge(999)
    gw.receipt(999)   # concrete method shared by all gateways
output
Stripe: charging 999
Receipt: StripeGateway charged 999
Razorpay: charging 999
Receipt: RazorpayGateway charged 999

"ABCs are great for plugin systems and APIs: you define what every plugin must do, ship the abstract class, and anyone building a plugin is guided exactly by what they must implement."

— ShurAI

🧠 Quiz — Q1

What happens when you try to instantiate an abstract class directly?

🧠 Quiz — Q2

What does marking a method with @abstractmethod do?

🧠 Quiz — Q3

An abstract class Animal has abstract method speak(). Class Dog(Animal) does not implement speak(). What happens when you write Dog()?

🧠 Quiz — Q4

What is the difference between an abstract method and a regular method in an ABC?