Искать
Вы превысили запрос на
0 знаков

67. Наследование и абстрактные суперклассы в Python

Не пройден
0
0

В предыдущем уроке в очередной раз поговорили про атрибуты и методы класса в Python. В этом уроке более детально разберемся с наследованием, способах связывания классов и абстрактными суперклассами.

Наследование

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

Вышеописанная модель наследования отлично работает из-за того, что сначала находятся имена в подклассах (в примере SubClass) до проверки суперклассов, за счет чего происходит переопределение атрибутов наследуемых суперклассов. Таким образом можно строить целые иерархии из классов и затем расширять их путем добавления новых подклассов, которые могут:

  • замещать унаследованные атрибуты;
  • предоставлять новые атрибуты;
  • расширять методы суперклассов, с помощью их переопределения.

Далее пример расширения суперкласса:

Пример (python)
class SuperClass:
    def display(self):
        print('Print SuperClass')

class SubClass(SuperClass):
    def display(self):
        print('Some sort of code')
        SuperClass.display(self)
        print('And some other code')

x = SubClass()
x.display() # => Some sort of code
            # => Print SuperClass
            # => And some other code 

Способы связывания классов

Рассмотрим другие способы связывания с суперклассом.

Пример (python)
class SuperClass:
    def method(self):
        print('Print SuperClass')
    def delegate(self):
        self.action()

class Inheritor(SuperClass): # просто наследуем методы
    pass

class Replacer(SuperClass): # полностью переопределяем метод
    def method(self):
        print('in Replacer.method')

class Extender(SuperClass): # расширяем поведение метода
    def method(self):
        print('starting Extender.method')
        SuperClass.method(self)
        print('ending Extender.method')

class Provider(SuperClass): # заполняем обязательный метод
    def action(self):
        print('in Provider.action')
              
if __name__ == '__main__':
    for c in (Inheritor, Replacer, Extender):
        print('
' + c.__name__ + ':')
        c().method()

    print('
Provider...')
    x = Provider()
    x.delegate() 

Вывод программы:

Пример (text)
Inheritor...
Print SuperClass

Replacer...
in Replacer.method

Extender...
starting Extender.method
Print SuperClass
ending Extender.method

Provider...
in Provider.action 

В примере мы определили пять классов: SuperClass, Inheritor, Replacer, Extender и Provider.

  • SuperClass - определяет два метода. Метод delegate() ожидает наличие в подклассе метода action().
  • Inheritor - просто наследует все от SuperClass.
  • Replacer - полностью переопределяет метод method().
  • Extender - добавляет новый функционал методу method().
  • Provider - реализует метод action(), который ожидается методом delegate() в суперклассе.

В Python все является объектами, поэтому мы создали кортеж (Inheritor, Replacer, Extender) из классов в цикле for и перебрали его. Далее поговорим на основе чего строятся объектно-ориентированные фреймворки в Python.

Абстрактные суперклассы

Абстрактность рассмотрим на примере класса Provider из предыдущего примера. Вот его фрагмент:

Пример (python)
class SuperClass:
    def method(self):
        print('Print SuperClass')
    def delegate(self):
        self.action()
        
class Provider(SuperClass):
    def action(self):
        print('in Provider.action')
              
if __name__ == '__main__':
    print('
Provider...')
    x = Provider()
    x.delegate() 

Что происходит с позиции наследования когда мы вызываем метод delegate() через экземпляр Provider? Сначала интерпретатор Python находит метод delegate() в суперклассе SuperClass. Экземпляр x передается в аргументе self как мы говорили ранее. Далее внутри метода delegate() суперкласса метод self.action() инициирует поиск в self и выше. Так как метод self ссылается на экземпляр класса Provider, то метод action() обнаруживается в подклассе Provider. Таким образом обычно строятся объекно-ориентированные фреймворки.

Определение

Абстрактный класс - класс, который ожидает от своих подклассов передачу частей своего поведения через наследование.

Чтобы сделать требования к подклассам более очевидными, разработчики используют оператор assert или добавляют генерацию исключения с помощью оператора raise.

Пример (python)
class SuperClass:
    def method(self):
        print('Print SuperClass')
    def delegate(self):
        self.action()
    def action(self):
        assert False, 'Метод action должен быть определен!'

class Provider(SuperClass):
    pass
    # def action(self):
    #     print('in Provider.action')
              
if __name__ == '__main__':
    x = Provider()
    x.delegate() # => AssertionError: Метод action должен быть определен! 

Сделать заглушку на метод с помощью оператора raise можно следующим образом:

Пример (python)
class SuperClass:
	# ...
    def action(self):
        raise NotImplementedError('Метод action должен быть определен!') 

В этом уроке более детально разобрались с наследованием, способах связывания классов и абстрактными суперклассами. В следующем уроке поговорим про пространство имен и строки документации.

Тест

Две секундочки...

Похожие уроки Codebra

@codebra_official
Подписывайся на наш Telegram-канал!
Новости, полезный материал,
программирование и ИБ
Основы объектно-ориентированного программирования (ООП) в PythonЗнакомство с Python
Продолжаем написание классов в PythonЗнакомство с Python
Написание модулей в PythonЗнакомство с Python
Работа с файлами в PythonЗнакомство с Python
Разбираемся с атрибутами и методами класса в PythonЗнакомство с Python
Типы данных в PythonЗнакомство с Python
Основы написания классов в PythonЗнакомство с Python
Генераторы и оператор yield в PythonЗнакомство с Python
Поиск хостов с помощью NmapРазведка и сканирование
Впервые на сайте Codebra?

Извините за это всплывающее окно, меня они тоже раздражают.

Если вас интересует компьютерная безопасность, реверс-инжиниринг и анализ бинарных файлов, то посмотрите вторую часть сайта Codebra: CodeSecure

Закрыть окно