Абстрактный класс ABC

Просто лого для статьи

Абстрактный класс – класс, содержащий один и более абстрактных методов.

Абстрактный метод – метод, который объявлен, но не реализован.

Абстрактный класс не может быть инстанциирован (создан его экземпляр). Нужно наследовать этот класс и реализовать (переопределить) все абстрактные методы, и только после этого можно создавать экземпляры такого наследника.

В Python нет синтаксической поддержки абстрактных классов, но есть встроенный модуль abc (расшифровка – abstract base classes), который помогает проектировать абстрактные сущности.

Абстрактный класс наследуют от ABC (Python 3.4+) или указывают метакласс ABCMeta (для Python 3.0+):

from abc import ABC, ABCMeta
class Hero(ABC):
    ...

# или:
class Hero(metaclass=ABCMeta):
    ...

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

from abc import ABC, abstractmethod
class Hero(ABC):
    @abstractmethod
    def attack(self):
        pass

Hero() – выдаст ошибку "TypeError: Can't instantiate abstract class Hero with abstract methods attack", которая говорит, что в классе Hero есть абстрактный метод attack. Мы вставили в него заглушку pass, но вообще там может быть какая-то реализация. Отнаследуем от героя Hero – конкретный подкласс лучника Archer:

class Archer(Hero):
    def attack(self):
        print('выстрел из лука')
Archer().attack()

Вот объект Archer мы можем уже создать и использовать реализацию метода attack

Кроме обычных методов, абстрактными можно обозначить и статические, классовые методы, а также свойства:

class C(ABC):
   @classmethod
   @abstractmethod
   def my_abstract_classmethod(cls):
       ...

   @staticmethod
   @abstractmethod
   def my_abstract_staticmethod():
       ...

   @property
   @abstractmethod
   def my_abstract_property(self):
       ...

   @my_abstract_property.setter
   @abstractmethod
   def my_abstract_property(self, val):
       ...

Абстрактные классы широко фигурируют в ООП, часто всплывают в шаблонах проектирования. Они говорят, что общий интерфейс уже обозначен, но этот класс еще не предназначен для использования, кроме как для наследования от него конкретных потомков.

Формально говоря, абстрактные классы для Python не являются чем-то необходимым в силу динамичности языка. Если мы выкинем все упоминания абстрактности классов и методов из рабочего кода, он продолжит работать, как и ранее. Абстрактные классы нужны на этапе проектирования или расширения кода, чтобы обеспечивать «правильные» взаимодействия новых классов, защищая от создания экземпляров абстрактных классов. Важно помнить, что эта защита срабатывает на этапе выполнения программы, а не компиляции, как в языках Java, C++ или C#!

Специально для канала @pyway. Подписывайтесь на мой канал в Телеграм @pyway 👈 

Добавить комментарий