Python

P
PythonHub
Progress 0%

Python

  • Home
  • History of Python
  • Applications of Python
  • Introduction To Python
    • What is Python
    • Character Set
    • Tokens in Python
    • Python Execution Mode
    • Variable And Identifiers
    • Data Types in Python
    • Operators And Expressions
    • Constants in Python
    • Assignment Statement
    • Input / Output in Python
    • Simple Python Scripts
    • Namespace in Python
    • šŸ“ Assignments
  • Operators in Python
    • Arithmetic Operators
    • Assignment Operators
    • Shorthand Assignment Operators
    • Relational Operators
    • Logical Operators
    • Bitwise Operators
    • Special Operators
    • šŸ“ Assignments
  • Input Output in Python
    • Accept Input
    • Output Formatting
    • šŸ“ Assignments
  • Conditional Statement
    • Decision Making
    • if Statement
    • IF-ELSE STATEMENT
    • IF-ELSE LADDER
    • NESTED IF-ELSE
    • Short Hand IF-ELSE
    • šŸ“ Assignments
  • Loops
    • Introduction to Loops
    • While Loop
    • Nested While Loop
    • šŸ“ While Loop Assignments
    • For Loop
    • For Loop Examples
    • Nested For Loop
    • Nested For Loop Examples
    • Infinite While Loops
    • Infinite For Loops
    • Break, Continue and Else in Loops
    • Difference Between For and While Loop
    • For Each Loop
    • šŸ“ For Each Assignments
    • šŸ“ All Loops Assignments
  • List
    • List in Python
    • Access List Elements
    • List Functions
    • Iterate (Loop) List
    • List Comprehension
    • šŸ“ Assignments
  • Tuple
    • Tuple in Python
    • Access Tuple Elements
    • Tuple Functions
    • Iterate (Loop) Tuple
    • Unpack Tuple
    • Tuple Comprehension
    • šŸ“ Assignments
  • Set
    • Set in Python
    • Access Set Elements
    • Set Methods
    • Iterate (Loop) Set
    • Pack/Unpack Set
    • Set Comprehension
    • šŸ“ Assignments
  • Dictionary
    • Dictionary
    • Access Dictionary Items
    • Dictionary Methods
    • Iterate (Loop) Dictionary
    • Formatting Dictionaries
    • Nested Dictionaries
    • Dictionary Comprehension
    • šŸ“ Assignments
  • Diff List Tuple Set Dictionary
    • List vs Tuple
    • List vs Set
    • List vs Dictionary
    • Tuple vs Set
    • Tuple vs Dictionary
    • Dictionary vs Set
    • šŸ“ Assignments
  • Exception
    • Error vs Exception
    • Types of Exception
    • Exception Handling
    • User Defined Exception
    • Logging Exception
    • šŸ“ Assignments
  • Functions
    • Introduction to Functions
    • Modular Programming
    • Types of Functions
    • Inbuilt Functions
    • Need For User-Defined Function
    • Elements of User Defined Function
    • Function Arguments
    • Nesting of Functions
    • Recursion
    • Global Local and Non Local
    • Python Lambda Functions
    • šŸ“ Assignments
  • Python Module
    • Introduction to Module
    • Inbuilt Modules in Python
    • User Defined Module
    • šŸ“ Assignments
  • File Handling
    • Introduction to Files
    • Create File
    • Read Files
    • Write to File
    • Rename File
    • Copy File
    • Move File
    • List Files in Directory
    • Binary Files
    • Zipping and Unzipping Files
    • šŸ“ Assignments
  • Strings
    • Basics of Strings
    • String Special Operators
    • String Formatting Operators
    • String Methods
    • šŸ“ Assignments
  • Regular Expressions
  • Python OOPS
    • Basics of Object Oriented
    • What are Classes and Objects?
    • Creating Class and Object
    • OOP vs Procedural Programming
    • Difference Between Classes and Objects
    • Constructors
    • Destructor
    • Built Class Methods and Attributes
    • Class and Instance Variables
    • Inheritance in Python
    • Single Inheritance
    • Multiple Inheritance
    • Multilevel Inheritance
    • Hierarchical Inheritance
    • Hybrid Inheritance
    • Abstraction
    • Method Overriding
    • Abstract Method
    • Interfaces in Python
    • Abstract Class vs Interface
    • Public, Private and Protected
    • Overloading vs Overriding
    • Inheritance vs Composition
    • Encapsulation
    • Polymorphism
    • Inner Classes
    • šŸ“ Assignments
  • Advanced Python
    • Iterator in Python
    • Generator in Python
    • Decorator in Python
    • Type Hints in Python
    • Async/Await Programming
    • Dataclasses in Python
    • Context Managers in Python
    • Property Decorator in Python
    • __slots__ in Python
    • Enums in Python
    • Walrus Operator in Python
    • Match-Case in Python
    • šŸ“ Assignments
  • Python Standard Library
    • Collections Module
    • Itertools Module
    • Functools Module
    • Datetime Module
    • JSON Module
    • OS Module
    • Sys Module
    • Random Module
    • Math Module
    • šŸ“ Assignments
  • Python Testing
    • Unit Testing in Python
    • Pytest Framework
    • Mocking in Python
    • šŸ“ Assignments
  • Python Best Practices
    • PEP 8 Style Guide
    • Docstrings in Python
    • Logging in Python
    • Code Optimization Tips
    • Debugging Techniques
    • šŸ“ Assignments
  • MySQL Database in Python
    • Introduction to MySQL with Python
    • DBMS vs File System
    • Connecting to MySQL Database
    • Create Database in MySQL
    • Create Table in MySQL
    • Insert Data in MySQL
    • Insert Multiple Rows
    • Select Data from MySQL
    • WHERE Clause in MySQL
    • Update Data in MySQL
    • Delete Data from MySQL
    • Parameterized Queries
    • Transaction Management
    • Error Handling
    • Connection Pooling
    • MySQL Drivers Guide
    • Joins in MySQL
    • Aggregation Functions
    • Backup MySQL Database
    • Best Practices
    • šŸ“ Assignments
  • MySQL Database Operations
    • SELECT Statement
    • MySQL Operators
    • DDL Statements
    • DML Statements
    • Subqueries
    • JOIN Operations
    • Aggregation
    • Case Study
    • šŸ“ Assignments
  • Graphics in Python
  • Threads in Python
    • Introduction to Threads
    • Process vs Threads
    • Concurrent Programming & GIL
    • Uses of Threads
    • Creating Threads
    • Single Tasking
    • Multi Tasking
    • Thread Synchronization
    • šŸ“ Assignments
  • Interview Questions & Answers
  • Python Case Studies
  • Multiple Choice Questions
  • šŸ“ Practice Problems
Get in Touch
  • tech2dsm@gmail.com

© Sankalan Data Tech

Python Language Interactive Tutorial

Python: Abstract Method

Python Abstract Method - Complete Guide

Learn how to define and implement abstract methods in Python.

Created by Sankalan Data Tech Team Verified
Data Engineers, Analysts, Scientists & Trainers
Created by experienced Python developers, data engineers, and data scientists to make programming easy through practical examples, real-world experience, and clear explanations.
On this page:
  • What is an Abstract Method?
  • Why Do We Need Abstract Methods?
  • The @abstractmethod Decorator
  • Implementing Abstract Methods
  • Concrete vs Abstract Methods
  • Real-World Examples
  • Best Practices
  • Try It Yourself
  • Quick Quiz
  • Frequently Asked Questions
Share this tutorial:
Twitter LinkedIn Facebook WhatsApp Reddit Telegram Email Copy Link
What You'll Learn Here
  • What is an abstract method — a method without implementation that must be overridden
  • Why we need them — enforcing a contract for child classes
  • The @abstractmethod decorator — how to declare abstract methods
  • Implementing abstract methods — providing concrete implementations
  • Concrete vs abstract — understanding the difference
  • Real-world use — practical examples you can use

What is an Abstract Method?

An abstract method is a method that is declared but not implemented in a class. It's like a placeholder — it tells the world "this method exists, but I'm not going to write the code for it here." The actual code must be provided by any class that inherits from this class.

Think of it like a job description. A job description says "the person in this role must be able to do X, Y, and Z." It doesn't tell you exactly how to do those things — it's up to the person who takes the job to figure that out. An abstract method is exactly that — a requirement that must be fulfilled.

In Python, abstract methods are created using the @abstractmethod decorator from the abc module. They can only exist inside abstract classes.

šŸ’” Key concept: An abstract method is a promise — "I promise this method exists, but I'm not implementing it here. You must implement it in your class." It enforces a contract between the abstract class and its children.

Why Do We Need Abstract Methods?

1

Enforcing a Contract

Abstract methods exist to enforce a contract. They say: "If you want to be a child of this class, you MUST have these methods." This ensures that all child classes have the same interface, making your code more predictable and easier to work with.

Without abstract methods, you might forget to implement a method in a child class — and your code would break at runtime. Abstract methods catch these errors early when you try to create an object, not when you try to use the missing method.

# Why abstract methods are important

from abc import ABC, abstractmethod

# Abstract class with abstract methods
class Worker(ABC):
    """A worker must be able to work and rest"""
    
    @abstractmethod
    def work(self):
        """Every worker must work — no exception"""
        pass
    
    @abstractmethod
    def rest(self):
        """Every worker must rest — no exception"""
        pass

# A good child class — implements all abstract methods
class Programmer(Worker):
    def work(self):
        return "Writing code"
    
    def rest(self):
        return "Taking a coffee break"

# Another good child class
class Teacher(Worker):
    def work(self):
        return "Teaching students"
    
    def rest(self):
        return "Grading papers"

# A bad child class — forgets to implement a method
# This would cause an error when you try to create it!
class BadWorker(Worker):
    def work(self):
        return "Working"
    # Missing rest() method

# Using the good classes
programmer = Programmer()
teacher = Teacher()

print("=== PROGRAMMER ===")
print(programmer.work())
print(programmer.rest())

print("\n=== TEACHER ===")
print(teacher.work())
print(teacher.rest())

# This would cause an error:
# bad = BadWorker()  # TypeError: Can't instantiate abstract class BadWorker with abstract method rest

print("\nāœ… Abstract methods catch missing implementations EARLY!")
print("Before you even use the object, Python tells you what's missing.")

Why abstract methods matter:

  • Enforce contracts — child classes must implement certain methods
  • Early error detection — catch missing implementations at instantiation time
  • Consistent interface — all child classes have the same methods
  • Better code quality — prevents runtime errors from missing methods
  • Design clarity — clearly shows what methods are required

Quick Check: What happens if a child class doesn't implement an abstract method? (Answer: You can't instantiate the child class — Python raises a TypeError)

The @abstractmethod Decorator

2

How to Declare Abstract Methods

In Python, you declare an abstract method using the @abstractmethod decorator. This decorator tells Python: "This method is abstract — it has no implementation and must be overridden by child classes."

The @abstractmethod decorator is part of the abc module (ABC stands for Abstract Base Class). You need to import it along with the ABC class that your abstract class inherits from.

# Using the @abstractmethod decorator

from abc import ABC, abstractmethod

# Correct way to create an abstract class with abstract methods
class Shape(ABC):
    """Abstract class with abstract methods"""
    
    @abstractmethod
    def area(self):
        """Calculate the area — must be implemented"""
        pass
    
    @abstractmethod
    def perimeter(self):
        """Calculate the perimeter — must be implemented"""
        pass
    
    # Concrete method — not abstract, can be used as-is
    def describe(self):
        return f"This is a shape"

# The @abstractmethod decorator can be used with other decorators
class Animal(ABC):
    @abstractmethod
    def sound(self):
        """Make a sound — must be implemented"""
        pass
    
    @abstractmethod
    def move(self):
        """Move — must be implemented"""
        pass

# You can also combine @abstractmethod with @classmethod or @staticmethod
class Repository(ABC):
    @abstractmethod
    def save(self, data):
        """Save data — must be implemented"""
        pass
    
    @abstractmethod
    def get(self, id):
        """Get data by id — must be implemented"""
        pass
    
    @classmethod
    @abstractmethod
    def create_empty(cls):
        """Create an empty repository — must be implemented"""
        pass

# Implementing the abstract methods
class Rectangle(Shape):
    def __init__(self, width, height):
        self.width = width
        self.height = height
    
    def area(self):
        return self.width * self.height
    
    def perimeter(self):
        return 2 * (self.width + self.height)

class Dog(Animal):
    def sound(self):
        return "Woof!"
    
    def move(self):
        return "Runs on four legs"

# Testing
rect = Rectangle(5, 3)
print(f"Area: {rect.area()}")       # 15
print(f"Perimeter: {rect.perimeter()}")  # 16
print(rect.describe())              # This is a shape (concrete method)

dog = Dog()
print(dog.sound())  # Woof!
print(dog.move())   # Runs on four legs

print("\nāœ… @abstractmethod creates a contract that child classes must fulfill!")
print("The decorator tells Python this method is required in child classes.")

@abstractmethod key points:

  • From abc module — must import @abstractmethod and ABC
  • No implementation — abstract methods only have a signature (and docstring)
  • Use pass — the body is typically just 'pass'
  • Can be combined — works with @classmethod and @staticmethod
  • Child must implement — or it remains abstract

Quick Check: What two things must you import from the abc module? (Answer: ABC and abstractmethod)

Implementing Abstract Methods

3

Providing Concrete Implementations

When a child class inherits from an abstract class with abstract methods, it must implement all of them. If it doesn't, the child class will also be abstract and you won't be able to create objects from it.

The implementation can be anything — as long as the method has the same name and a body. The abstract class doesn't care what you do, it just cares that you did something.

# Implementing abstract methods

from abc import ABC, abstractmethod
import math

class Shape(ABC):
    """Abstract class — defines what a shape must do"""
    
    @abstractmethod
    def area(self):
        pass
    
    @abstractmethod
    def perimeter(self):
        pass
    
    @abstractmethod
    def get_name(self):
        pass

# 1. Fully implemented child class
class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius
    
    def area(self):
        return math.pi * self.radius ** 2
    
    def perimeter(self):
        return 2 * math.pi * self.radius
    
    def get_name(self):
        return "Circle"

# 2. Another fully implemented child class
class Square(Shape):
    def __init__(self, side):
        self.side = side
    
    def area(self):
        return self.side ** 2
    
    def perimeter(self):
        return 4 * self.side
    
    def get_name(self):
        return "Square"

# 3. Partially implemented child class (missing a method)
class Triangle(Shape):
    def __init__(self, base, height, side1, side2, side3):
        self.base = base
        self.height = height
        self.side1 = side1
        self.side2 = side2
        self.side3 = side3
    
    def area(self):
        return 0.5 * self.base * self.height
    
    # Missing perimeter() — this will cause an error when instantiating
    # Missing get_name() — this will cause an error when instantiating

# 4. Child class that extends abstract class but doesn't implement all methods
class AbstractChild(Shape):
    def area(self):
        return 0
    # Missing perimeter() and get_name() — can't instantiate

# Using fully implemented classes
print("=== CIRCLE ===")
circle = Circle(5)
print(f"Name: {circle.get_name()}")
print(f"Area: {circle.area():.2f}")
print(f"Perimeter: {circle.perimeter():.2f}")

print("\n=== SQUARE ===")
square = Square(4)
print(f"Name: {square.get_name()}")
print(f"Area: {square.area()}")
print(f"Perimeter: {square.perimeter()}")

# This would cause an error:
# triangle = Triangle(10, 5, 3, 4, 5)  # TypeError: Can't instantiate abstract class Triangle

print("\nāœ… You must implement ALL abstract methods to create a concrete class!")
print("Missing even one makes the class abstract and uninstantiable.")

Implementing abstract methods key points:

  • All must be implemented — every abstract method must have a concrete implementation
  • Same name required — the method name must match exactly
  • Any implementation works — as long as there's a body
  • Missing any = abstract — if one is missing, you can't create objects
  • Check at instantiation — Python checks when you try to create an object

Quick Check: What happens if a child class implements only some abstract methods? (Answer: The child class remains abstract and can't be instantiated)

Concrete vs Abstract Methods

4

Understanding the Difference

The main difference between concrete and abstract methods is implementation. A concrete method has a body — it actually does something. An abstract method has no body — it's just a placeholder.

Abstract methods are like empty containers waiting to be filled. Concrete methods are already full and ready to use. Abstract classes can have both — this gives you the best of both worlds: enforced requirements and shared functionality.

# Concrete methods vs Abstract methods

from abc import ABC, abstractmethod

class Document(ABC):
    """Abstract class with both abstract and concrete methods"""
    
    # Abstract method — no implementation
    @abstractmethod
    def save(self):
        """Save the document — must be implemented"""
        pass
    
    # Abstract method — no implementation
    @abstractmethod
    def open(self):
        """Open the document — must be implemented"""
        pass
    
    # Concrete method — has implementation
    def get_extension(self):
        """Get the file extension — shared by all documents"""
        return ".docx"
    
    # Concrete method — has implementation
    def get_size(self):
        """Get the document size — shared by all documents"""
        return "100 KB"
    
    # Concrete method — has implementation
    def print_info(self):
        """Print document info — shared by all documents"""
        return f"Document (size: {self.get_size()})"

class PDFDocument(Document):
    """Concrete class — implements all abstract methods"""
    
    def save(self):
        return "Saving PDF document"
    
    def open(self):
        return "Opening PDF document"
    
    # Override concrete method if needed
    def get_extension(self):
        return ".pdf"

class WordDocument(Document):
    """Concrete class — implements all abstract methods"""
    
    def save(self):
        return "Saving Word document"
    
    def open(self):
        return "Opening Word document"
    
    # Uses parent's concrete methods as-is

# Testing
print("=== PDF DOCUMENT ===")
pdf = PDFDocument()
print(pdf.save())           # Abstract method implemented
print(pdf.open())           # Abstract method implemented
print(pdf.get_extension())  # Concrete method overridden
print(pdf.get_size())       # Concrete method inherited
print(pdf.print_info())     # Concrete method inherited

print("\n=== WORD DOCUMENT ===")
word = WordDocument()
print(word.save())          # Abstract method implemented
print(word.open())          # Abstract method implemented
print(word.get_extension()) # Concrete method inherited
print(word.get_size())      # Concrete method inherited
print(word.print_info())    # Concrete method inherited

print("\nāœ… Abstract methods = no body (must be overridden)")
print("āœ… Concrete methods = has body (can be used directly)")
print("Abstract classes can have BOTH types!")
print("   - Abstract methods enforce the contract")
print("   - Concrete methods provide shared functionality")

Concrete vs Abstract key points:

  • Abstract method — has no body, only signature (use pass)
  • Concrete method — has a body with actual code
  • Abstract methods must be overridden — by all concrete child classes
  • Concrete methods can be used as-is — or overridden if needed
  • Both can exist in the same class — mix and match as needed

Quick Check: What's the difference between an abstract method and a concrete method? (Answer: Abstract methods have no body; concrete methods have a full implementation)

Real-World Examples

5

Seeing Abstract Methods in Action

# Real-world example: A Data Export System

from abc import ABC, abstractmethod

class DataExporter(ABC):
    """Abstract class — defines how to export data"""
    
    @abstractmethod
    def connect(self):
        """Connect to the data source — must be implemented"""
        pass
    
    @abstractmethod
    def fetch_data(self):
        """Fetch the data — must be implemented"""
        pass
    
    @abstractmethod
    def format_data(self, data):
        """Format the data for export — must be implemented"""
        pass
    
    @abstractmethod
    def export(self, data, destination):
        """Export the data — must be implemented"""
        pass
    
    # Concrete method — shared by all exporters
    def log_export(self, records_count):
        return f"Exported {records_count} records"
    
    # Concrete method — shared by all exporters
    def validate_destination(self, destination):
        if not destination:
            return "No destination provided"
        return f"Valid destination: {destination}"

# Concrete class 1 — CSV Exporter
class CSVExporter(DataExporter):
    def connect(self):
        return "Connected to CSV data source"
    
    def fetch_data(self):
        return {"headers": ["Name", "Age", "City"], "rows": [["Alice", 30, "NYC"], ["Bob", 25, "LA"]]}
    
    def format_data(self, data):
        headers = data["headers"]
        rows = data["rows"]
        csv_lines = [",".join(headers)]
        for row in rows:
            csv_lines.append(",".join(str(item) for item in row))
        return "\n".join(csv_lines)
    
    def export(self, data, destination):
        formatted = self.format_data(data)
        self.log_export(len(data["rows"]))
        return f"CSV exported to {destination}:\n{formatted}"

# Concrete class 2 — JSON Exporter
class JSONExporter(DataExporter):
    def connect(self):
        return "Connected to JSON data source"
    
    def fetch_data(self):
        return {"users": [{"name": "Alice", "age": 30}, {"name": "Bob", "age": 25}]}
    
    def format_data(self, data):
        import json
        return json.dumps(data, indent=2)
    
    def export(self, data, destination):
        formatted = self.format_data(data)
        self.log_export(len(data["users"]))
        return f"JSON exported to {destination}:\n{formatted}"

# Concrete class 3 — Excel Exporter
class ExcelExporter(DataExporter):
    def connect(self):
        return "Connected to Excel data source"
    
    def fetch_data(self):
        return {"sheet": "Sheet1", "data": [["Name", "Age"], ["Alice", 30], ["Bob", 25]]}
    
    def format_data(self, data):
        sheet = data["sheet"]
        rows = data["data"]
        formatted = [f"Sheet: {sheet}"]
        for row in rows:
            formatted.append(" | ".join(str(item) for item in row))
        return "\n".join(formatted)
    
    def export(self, data, destination):
        formatted = self.format_data(data)
        self.log_export(len(data["data"]) - 1)
        return f"Excel exported to {destination}:\n{formatted}"

# Using the exporters
print("=" * 50)
print("DATA EXPORT SYSTEM")
print("=" * 50)

def export_data(exporter, destination):
    """Function that works with any exporter (polymorphism)"""
    print(exporter.connect())
    data = exporter.fetch_data()
    result = exporter.export(data, destination)
    print(result)
    print(exporter.validate_destination(destination))

print("\n=== CSV EXPORT ===")
csv_exporter = CSVExporter()
export_data(csv_exporter, "data.csv")

print("\n=== JSON EXPORT ===")
json_exporter = JSONExporter()
export_data(json_exporter, "data.json")

print("\n=== EXCEL EXPORT ===")
excel_exporter = ExcelExporter()
export_data(excel_exporter, "data.xlsx")

print("\nāœ… Abstract methods enforce a consistent interface across all exporters!")
print("Each exporter implements the same methods but in different ways.")

Real-world example key points:

  • Abstract class — DataExporter defines the interface (connect, fetch, format, export)
  • Concrete methods — log_export() and validate_destination() are shared
  • CSVExporter — implements abstract methods for CSV format
  • JSONExporter — implements abstract methods for JSON format
  • ExcelExporter — implements abstract methods for Excel format
  • export_data() — works with any exporter (polymorphism)

Quick Check: What does the export_data function demonstrate? (Answer: Polymorphism — it works with any exporter class that implements the DataExporter interface)

Best Practices for Abstract Methods

6

Using Abstract Methods Effectively

# Best practices for abstract methods

from abc import ABC, abstractmethod

# 1. Use docstrings to document abstract methods
class Validator(ABC):
    @abstractmethod
    def validate(self, data):
        """
        Validate the given data.
        
        Args:
            data: The data to validate
            
        Returns:
            bool: True if valid, False otherwise
            
        Raises:
            ValueError: If validation fails with detailed message
        """
        pass

# 2. Keep abstract methods focused and clear
#  Good — one clear responsibility
class Parser(ABC):
    @abstractmethod
    def parse(self, content):
        """Parse the given content into structured data"""
        pass

#  Bad — too many responsibilities
class BadParser(ABC):
    @abstractmethod
    def parse(self, content):
        pass
    @abstractmethod
    def save(self, data):
        pass
    @abstractmethod
    def format(self, data):
        pass  # These are different responsibilities!

# 3. Use abstract methods to define a contract
class Repository(ABC):
    @abstractmethod
    def get(self, id):
        pass
    
    @abstractmethod
    def save(self, entity):
        pass
    
    @abstractmethod
    def delete(self, id):
        pass
    
    @abstractmethod
    def list_all(self):
        pass

# 4. Provide meaningful error messages
class Printer(ABC):
    @abstractmethod
    def print_document(self, document):
        """Print a document — must be implemented by all printer types"""
        pass

class NetworkPrinter(Printer):
    def print_document(self, document):
        # Implementation
        return f"Printing to network: {document}"

# 5. Use abstract methods with default implementations when appropriate
class Logger(ABC):
    @abstractmethod
    def log(self, message):
        pass
    
    def log_error(self, message):
        """Concrete method that uses log() — can be overridden"""
        self.log(f"ERROR: {message}")

# 6. Name abstract methods clearly
#  Good — clear and descriptive
class Task(ABC):
    @abstractmethod
    def execute(self):
        pass
    
    @abstractmethod
    def rollback(self):
        pass

#  Bad — vague names
class BadTask(ABC):
    @abstractmethod
    def do(self):
        pass
    
    @abstractmethod
    def undo(self):
        pass

# 7. Don't overuse abstract methods
#  Only use when you need to enforce a contract
class SimpleClass(ABC):
    #  Overkill for something simple
    @abstractmethod
    def get_value(self):
        pass  # This could just be a concrete method

# 8. Test abstract method implementations
class Tester(ABC):
    @abstractmethod
    def run_test(self):
        pass

class MyTester(Tester):
    def run_test(self):
        print("Test running...")
        return True

# Testing
tester = MyTester()
print(tester.run_test())

Best practices summary:

  • Use docstrings — document what the abstract method should do
  • Keep it focused — each abstract method should have one responsibility
  • Define a contract — abstract methods specify what child classes must do
  • Provide error messages — make it clear what's required
  • Use default implementations — when appropriate, provide concrete methods too
  • Name clearly — use descriptive names for abstract methods
  • Don't overuse — not everything needs to be abstract
  • Test implementations — make sure child classes work correctly

Quick Check: When should you use an abstract method? (Answer: When you want to enforce that all child classes implement a specific method)

Try It Yourself

Experiment with abstract methods in the editor below.

Loading Pyodide... 0%
Python Code Editor
========================================
ABSTRACT METHODS PRACTICE
========================================

1. CREATING AN ABSTRACT CLASS

2. CREATING CONCRETE CLASSES

3. USING THE CLASSES
DICTIONARY STORAGE:
Stored: user1 = Alice
Stored: user2 = Bob
Alice
Keys: ['user1', 'user2']
Deleted: user1
Keys: ['user2']

FILE STORAGE:
Stored in file data.txt: product1 = Laptop
Stored in file data.txt: product2 = Phone
Laptop
Deleted from file: product2

4. ABSTRACT METHODS IN ACTION
Both classes implement the same interface:
- store()
- retrieve()
- delete()
But each does it differently!

Abstract methods practice complete!
šŸ†

You've Got It!

You now understand abstract methods in Python. You know how to define them using @abstractmethod, implement them in child classes, and use them to enforce contracts.

Quick Quiz

Test what you've learned:

1. What is an abstract method?
2. What decorator is used to declare an abstract method?
3. What happens if a child class doesn't implement all abstract methods?
4. Can an abstract class have both abstract and concrete methods?
5. What module must you import to use abstract methods?

Frequently Asked Questions

What's the difference between an abstract method and method overriding? ā–¼

Abstract methods are methods without implementation that must be overridden by child classes. Method overriding is the act of providing a new implementation for any method (abstract or concrete). Abstract methods force overriding; concrete methods allow it optionally.

Can an abstract method have a body? ā–¼

Technically, you can give an abstract method a body in Python, but it's not recommended. The purpose of an abstract method is to have no implementation. If you want to provide a default implementation, use a concrete method instead. The abstract method should only contain a docstring and the word 'pass'.

Can I create an object from an abstract class? ā–¼

No, you cannot create an object from an abstract class. That's the whole point of abstract classes — they're meant to be used as blueprints for other classes. If you try to instantiate an abstract class, Python raises a TypeError.

What's a common interview question about abstract methods? ā–¼

Common questions include: "What is an abstract method and why is it useful?" "What is the difference between an abstract method and a concrete method?" "How do you declare an abstract method in Python?" "What happens if a child class doesn't implement an abstract method?"

When should I use abstract methods? ā–¼

Use abstract methods when you want to enforce a contract — when you want to guarantee that all child classes have certain methods. Examples include: database connectors (all must have connect, query, close), exporters (all must have export, format), or payment processors (all must have process, refund, get_status).

Can abstract methods be static or class methods? ā–¼

Yes! You can combine @abstractmethod with @staticmethod or @classmethod. The order matters — you need to apply @abstractmethod first, then the other decorator. Example: @abstractmethod @staticmethod def method(): pass. This enforces that child classes implement a static or class method.

Where to Go From Here

Now that you understand abstract methods, check out these related topics:

Interfaces in Python

Learn about implementing interfaces using abstract methods.

Learn More →

Abstract Class vs Interface

Learn the key differences between these two concepts.

Learn More →

Method Overriding

Learn more about overriding methods in child classes.

Learn More →
Interview Resources
  • Python Syntax & Variables Interview Questions
  • Top SQL Interview Questions & Answers
  • SQL Joins: Displaying Data from Multiple Tables FAQ
  • Python Lists and Dictionaries Interview Questions
  • Python OOP Interview Questions
  • SQL Set Operators Interview Questions
Previous: Method Overriding Next: Interfaces →