Перейти к содержанию

Объектно-ориентированный Python: наследование и super()

Начало урока

Наследование и super()

Стройте новые классы на основе существующих, а не с нуля

Главная идея: Наследование позволяет новому классу переиспользовать данные и поведение существующего класса. Существующий класс — это базовый (или родительский); новый класс — производный (или дочерний). Дочерний получает всё, что есть у родителя, и может это дополнить или изменить. super() — это способ для дочернего класса сотрудничать с родителем, а не молча его заменять.
К концу этой темы вы сможете:
  • объявлять производный класс через class Child(Parent): и объяснять связь is-a («является»),
  • вызывать __init__ родителя (и другие методы) через super(),
  • переопределять метод и понимать, когда его расширять, а когда заменять,
  • выбирать между наследованием и композицией по признаку is-a или has-a,
  • читать небольшую иерархию классов и предсказывать, какой метод выполнится.

1. Базовые и производные классы

Вы уже умеете писать отдельный класс с __init__ и методами. Наследование нужно, когда два класса делят много общего поведения и вы не хотите дублировать его дважды. Допустим, вы моделируете животных. У каждого животного есть имя и оно умеет есть; лаять умеют лишь некоторые. Вместо того чтобы повторять код имени и еды в Dog, Cat и Bird, вы кладёте общие части в один базовый класс и позволяете каждому конкретному животному наследоваться от него.

Проверка на наследование — это связь is-a («является»): Dog является Animal, SavingsAccount является BankAccount. Если такое предложение звучит верно, наследование — кандидат. Если же вы сказали бы has-a («имеет»), например Car имеет Engine, — это композиция, о ней в разделе 6.

class Animal:            # base / parent class
    def __init__(self, name):
        self.name = name

    def eat(self):
        return self.name + " is eating"

class Dog(Animal):      # derived / child class -- Dog IS-A Animal
    def bark(self):
        return "Woof!"

d = Dog("Rex")
print(d.eat())          # inherited from Animal
print(d.bark())         # defined on Dog

Вывод:

Rex is eating
Woof!

Обратите внимание: Dog нигде не объявляет __init__ или eat, но d.eat() работает. Python не нашёл eat в Dog, поэтому заглянул в родителя Animal и взял его. Этот поиск вверх — суть наследования.

Продолжите этот урок на YourAIZone

В полном уроке — объяснение целиком, разобранные примеры, частые ошибки, тесты с мгновенной проверкой и ИИ-репетитор. Начните сразу как гость или создайте аккаунт, чтобы сохранять прогресс.

В полном уроке

  • Объяснение целиком
  • Разобранные примеры
  • Частые ошибки и как их избежать
  • Тестовые вопросы: 15
  • ИИ-репетитор, который отвечает на вопросы по теме
  • Отслеживание прогресса для ученика, родителей и учителя