Шаг 143.
Основы языка Python.
Объектно-ориентированное программирование (ООП). Абстрактные методы

    На этом шаге мы рассмотрим определение и использование таких методов.

    Абстрактные методы содержат только определение метода без реализации. Предполагается, что класс-потомок должен переопределить метод и реализовать его функциональность. Чтобы такое предположение сделать более очевидным, часто внутри абстрактного метода возбуждают исключение:

class Class1:
    def func(self, x):    # Абстрактный метод
        # Возбуждаем исключение с помощью raise
        raise NotImplementedError("Необходимо переопределить метод")
    
class Class2(Class1):     # Наследуем абстрактный метод
    def func(self, x):    # Переопределяем метод
        print(x)
        
class Class3(Class1):     # Класс не переопределяет метод
    pass

c2 = Class2()
c2.func(50)	# Выведет: 50
c3 = Class3()
try:            # Перехватываем исключения
    c3.func(50)	# Ошибка. Метод func() не переопределен
except NotImplementedError as msg:
    print(msg)  # Выведет: Необходимо переопределить метод
Архив с файлом можно взять здесь.

    Результат работы приложения:

50
Необходимо переопределить метод

    В состав стандартной библиотеки входит модуль abc. В этом модуле определен декоратор @abstractmethod, который позволяет указать, что метод, перед которым расположен декоратор, является абстрактным. При попытке создать экземпляр класса-потомка, в котором не переопределен абстрактный метод, возбуждается исключение TypeError. Рассмотрим использование декоратора @abstractmethod на примере:

from abc import ABCMeta, abstractmethod
class Class1(metaclass=ABCMeta):
    @abstractmethod
    def func(self, x):    # Абстрактный метод
        pass
 
class Class2(Class1):     # Наследуем абстрактный метод
    def func(self, x):    # Переопределяем метод
        print(x)

class Class3(Class1):     # Класс не переопределяет метод
    pass

c2 = Class2()
c2.func(50)               # Выведет: 50
try:
    c3 = Class3()         # Ошибка. Метод func не переопределен
    c3.func(50)
except TypeError as msg:
    print(msg)            # Can't instantiate abstract class Class3
                          # with abstract methods func
Архив с файлом можно взять здесь.

    Результат работы приложения:

50
Can't instantiate abstract class Class3 with abstract methods func

    Имеется возможность создания абстрактных статических методов и абстрактных методов класса, для чего необходимые декораторы указываются одновременно, друг за другом. Для примера объявим класс с абстрактными статическим методом и методом класса:

from abc import ABCMeta, abstractmethod
class MyClass(metaclass=ABCMeta):
    @staticmethod
    @abstractmethod
    def static_func(self, x):    # Абстрактный статический метод
        pass
 
    @classmethod
    @abstractmethod
    def class_func(self, x):    # Абстрактный метод класса
        pass
Архив с файлом можно взять здесь.


   Примечание. В версиях Python, предшествующих 3.3, для определения абстрактного статического метода предлагалось использовать декоратор @abstractstaticmethod, а для определения абстрактного метода класса - декоратор @abstractclassmethod. Оба этих декоратора определены в том же модуле abc. Однако, начиная с Python 3.3, эти декораторы объявлены нерекомендованными к использованию.

    На следующем шаге мы рассмотрим ограничение доступа к идентификаторам внутри класса.




Предыдущий шаг Содержание Следующий шаг