Start learning free

LESSON 185 OF 344 · OBJECT-ORIENTED PROGRAMMING

Abstract Classes in Python: ABC and @abstractmethod

Lesson Read the full explanation

TL ; DR:

An abstract class is a class you can't instantiate directly — it's a half-finished template. It can declare methods with no body (abstract methods) that any concrete subclass must implement.


from abc import ABC, abstractmethod
class Animal(ABC):
    @abstractmethod
    def speak(self): pass
class Dog(Animal):
    def speak(self):
        print("Woof")


Full lesson:

Sometimes you want to capture shared behavior across a family of classes without committing to one concrete implementation. For example, every Animal can speak(), but exactly how depends on whether it's a Dog or a Cat. That's what abstract classes are for.

Two superpowers

  1. You can't write new Animal() directly — the compiler/runtime stops you. You have to pick a concrete subclass.
  2. Any subclass MUST implement every abstract method, or the compiler/runtime complains. The abstract class is a contract with teeth.

Mixing abstract and concrete

An abstract class can also have concrete methods (with bodies) and fields. Those are shared by all subclasses for free, just like normal inheritance. Only the methods marked abstract require an override.

Notes by language

  • C# / Java — keyword abstract on the class and on the method.
  • Python — inherit from abc.ABC and decorate the method with @abstractmethod.
  • JavaScript — no built-in support. The convention is a parent class whose method throws an error if not overridden.
  • C++ — a method ending with = 0 is "pure virtual"; a class with any pure virtual method is abstract.

Your task

The abstract Animal class is already defined. Create a concrete Dog subclass and implement the speak method so it prints "Woof". The harness builds a Dog and calls speak().

Expected output:

Woof
STEP 1 OF 2
    Ctrl + Enter to check

    PYTHON · OBJECT-ORIENTED PROGRAMMING

    Abstract Classes in Python, explained

    What an abstract class is

    Sometimes you want to describe what a whole family of classes can do without committing to how. Every animal can speak(), but how depends on whether it is a dog or a cat. An abstract class captures that: it is a half-finished template that you cannot instantiate directly. It declares methods with no real implementation, called abstract methods, and every concrete subclass must supply them.

    That gives an abstract class two properties:

    1. You cannot create an object of the abstract class itself. You must pick a concrete subclass.
    2. A subclass that leaves any abstract method unimplemented cannot be instantiated either. The abstract class is a contract that Python actually checks.

    The syntax in Python

    Python's tools live in the abc module. The class inherits from ABC, and each abstract method gets the @abstractmethod decorator:

    from abc import ABC, abstractmethod
    
    class Animal(ABC):
        @abstractmethod
        def speak(self): pass
    
    class Dog(Animal):
        def speak(self):
            print("Woof")
    

    The body of an abstract method is usually just pass, since the subclasses provide the real code. Now try to break the contract:

    class Lazy(Animal):
        pass
    
    Animal()
    Lazy()
    
    TypeError: Can't instantiate abstract class Animal without an implementation for abstract method 'speak'
    

    The first line raises the error shown above. Lazy() would raise the same kind of TypeError for its own name, since Lazy never implemented speak. Python stops at creation time, before any method is called, so the mistake shows up early.

    Mixing abstract and concrete methods

    An abstract class may also contain ordinary methods with bodies and ordinary attributes. Subclasses inherit them as usual, and only the methods marked abstract must be overridden. Concrete methods can even call the abstract ones, relying on the subclass to fill them in:

    class Animal(ABC):
        @abstractmethod
        def speak(self): pass
    
        def intro(self):
            print("I say:")
            self.speak()
    
    Dog().intro()
    
    I say:
    Woof
    

    Here intro is written once in Animal and works for every subclass, each producing its own sound. That is polymorphism combined with shared code.

    The ABC base matters

    The decorator alone does nothing. A class that does not inherit from ABC can use @abstractmethod without any error, and its objects can still be created. Both parts are required for Python to enforce the contract.

    The lesson's exercise

    The starter code already holds the abstract Animal and, at the bottom, rex = Dog() followed by rex.speak(). The Dog class is missing, so the program would fail with a NameError.

    1. Declare the concrete subclass. Write class Dog(Animal): below Animal. Python cannot create Animal objects, so the program needs a class it can instantiate.
    2. Implement the abstract method. Inside Dog, write def speak(self): with print("Woof") in its body. If you skip this, Dog() raises the same TypeError as Animal(), because the abstract method is still unimplemented.
    from abc import ABC, abstractmethod
    
    class Animal(ABC):
        @abstractmethod
        def speak(self): pass
    
    class Dog(Animal):
        def speak(self):
            print("Woof")
    
    rex = Dog()
    rex.speak()
    
    Woof
    

    Common mistakes

    • Misspelling the method name. Defining Speak or speek in Dog leaves speak abstract, so Dog() still fails.
    • Forgetting the base class. Without ABC, Animal() is accepted silently and no contract exists.
    • Instantiating the abstract class. Animal() is an error by design. Create a concrete subclass instead.
    • Expecting a missing implementation to fail only when called. The error comes when the object is created.

    Abstract classes in other languages

    Java and C# use an abstract keyword on both the class and the method. C++ marks a method with = 0, making it pure virtual. JavaScript has no built-in support, and the usual substitute is a parent method that throws an error. Python sits in the middle: the check exists, but it comes from a library module rather than a keyword.

    Key takeaways

    • An abstract class is a template that cannot be instantiated.
    • In Python, inherit from abc.ABC and mark methods with @abstractmethod.
    • A subclass must implement every abstract method before it can be instantiated.
    • Abstract classes can mix required methods with ordinary shared ones.
    Keep going with PythonAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free