Python Abstract Classes

Created with Sketch.

Python Abstract Classes

 

Summary: in this tutorial, you’ll learn about Python Abstract classes and how to use it to create a blueprint for other classes.

Introduction to Python Abstract Classes

In object-oriented programming, an abstract class is a class that cannot be instantiated. However, you can create classes that inherit from an abstract class.

Typically, you use an abstract class to create a blueprint for other classes.

Similarly, an abstract method is a method without an implementation. An abstract class may or may not include abstract methods.

Python doesn’t directly support abstract classes. But it does offer a module that allows you to define abstract classes.

To define an abstract class, you use the abc (abstract base class) module.

The abc module provides you with the infrastructure for defining abstract base classes.

For example:

from abc import ABC

class AbstractClassName(ABC):
pass

Code language: Python (python)

To define an abstract method, you use the @abstractmethod decorator:

from abc import ABC, abstractmethod

class AbstractClassName(ABC):
@abstractmethod
def abstract_method_name(self):
pass

Code language: Python (python)

Python abstract class example

Suppose that you need to develop a payroll program for a company.

The company has two groups of employees: full-time employees and hourly employees. The full-time employees get a fixed salary while the hourly employees get paid by hourly wages for their services.

The payroll program needs to print out a payroll that includes employee names and their monthly salaries.

To model the payroll program in an object-oriented way, you may come up with the following classes: Employee, FulltimeEmployee, HourlyEmployee, and Payroll.

To structure the program, we’ll use modules, where each class is placed in a separate module (or file).

The Employee class

The Employee class represents an employee, either full-time or hourly. The Employee class should be an abstract class because there’re only full-time employees and hourly employees, no general employees exist.

The Employee class should have a property that returns the full name of an employee. In addition, it should have a method that calculates salary. The method for calculating salary should be an abstract method.

The following defines the Employee abstract class:

from abc import ABC, abstractmethod

class Employee(ABC):
def __init__(self, first_name, last_name):
self.first_name = first_name
self.last_name = last_name

@property
def full_name(self):
return f"{self.first_name} {self.last_name}"

@abstractmethod
def get_salary(self):
pass

Code language: Python (python)

The FulltimeEmployee class

The FulltimeEmployee class inherits from the Employee class. It’ll provide the implementation for the get_salary() method.

Since full-time employees get fixed salaries, you can initialize the salary in the constructor of the class.

The following illustrates the FulltimeEmployee class:

class FulltimeEmployee(Employee):
def __init__(self, first_name, last_name, salary):
super().__init__(first_name, last_name)
self.salary = salary

def get_salary(self):
return self.salary

Code language: Python (python)

The HourlyEmployee class

The HourlyEmployee also inherits from the Employee class. However, hourly employees get paid by working hours and their rates. Therefore, you can initialize this information in the constructor of the class.

To calculate the salary for the hourly employees, you multiply the working hours and rates.

The following shows the HourlyEmployee class:

class HourlyEmployee(Employee):
def __init__(self, first_name, last_name, worked_hours, rate):
super().__init__(first_name, last_name)
self.worked_hours = worked_hours
self.rate = rate

def get_salary(self):
return self.worked_hours * self.rate

Code language: Python (python)

The Payroll class

The Payroll class will have a method that adds an employee to the employee list and print out the payroll.

Since fulltime and hourly employees share the same interfaces (full_time property and get_salary() method). Therefore, the Payroll class doesn’t need to distinguish them.

The following shows the Payroll class:

class Payroll:
def __init__(self):
self.employee_list = []

def add(self, employee):
self.employee_list.append(employee)

def print(self):
for e in self.employee_list:
print(f"{e.full_name} \t ${e.get_salary()}")

Code language: Python (python)

The main program

The following app.py uses the FulltimeEmployee, HourlyEmployee, and Payroll classes to print out the payroll of five employees.

from fulltimeemployee import FulltimeEmployee
from hourlyemployee import HourlyEmployee
from payroll import Payroll

payroll = Payroll()

payroll.add(FulltimeEmployee('John', 'Doe', 6000))
payroll.add(FulltimeEmployee('Jane', 'Doe', 6500))
payroll.add(HourlyEmployee('Jenifer', 'Smith', 200, 50))
payroll.add(HourlyEmployee('David', 'Wilson', 150, 100))
payroll.add(HourlyEmployee('Kevin', 'Miller', 100, 150))

payroll.print()

Code language: Python (python)

Output:

John Doe $6000
Jane Doe $6500
Jenifer Smith $10000
David Wilson $15000
Kevin Miller $15000

Code language: Python (python)

When to use abstract classes

In practice, you use abstract classes to share the code among several closely related classes. In the payroll program, all subclasses of the Employee class share the same full_name property.

Summary

  • Abstract classes are classes that you cannot create instances from.
  • Use abc module to define abstract classes.

Leave a Reply

Your email address will not be published. Required fields are marked *