Наследуется ли логика конструктора (__init__) от родительского класса в Python?

«Наследуется ли логика конструктора (__init__) от родительского класса в Python?» — вопрос из категории ООП, который задают на 24% собеседований AQA / Automation. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Нет, не наследуется автоматически. Если дочерний класс определяет свой собственный метод __init__, он полностью переопределяет (замещает) конструктор родительского класса. Это может привести к проблемам, если логика инициализации родителя (например, установка обязательных атрибутов) не будет выполнена.

Чтобы корректно унаследовать и расширить логику родительского конструктора, необходимо явно вызвать его с помощью функции super():

class Vehicle:
    def __init__(self, brand, model):
        # Родительский конструктор устанавливает базовые атрибуты
        self.brand = brand
        self.model = model
        print(f"Инициализирован Vehicle: {brand} {model}")

class Car(Vehicle):
    def __init__(self, brand, model, fuel_type):
        # 1. Явный вызов конструктора родительского класса
        super().__init__(brand, model)
        # 2. Добавление специфичной для Car логики
        self.fuel_type = fuel_type
        print(f"Тип топлива: {fuel_type}")

# Создание объекта
my_car = Car("Toyota", "Camry", "hybrid")
# Вывод:
# Инициализирован Vehicle: Toyota Camry
# Тип топлива: hybrid

Важные нюансы:

  • Если __init__ не определен в дочернем классе, Python будет использовать цепочку наследования и найдет первый __init__ в родительских классах.
  • super() обеспечивает корректный порядок разрешения методов (MRO), что критично при множественном наследовании.
  • Позиционные и именованные аргументы нужно передавать согласованно между конструкторами родителя и потомка.

С точки зрения тестирования (в контексте QA/ООП):

  • При написании unit-тестов для классов с наследованием нужно убедиться, что тесты проверяют корректную инициализацию как унаследованных от родителя атрибутов, так и специфичных для потомка.
  • Тест-кейс должен покрывать сценарий, когда дочерний класс не вызывает super().__init__(), чтобы проверить, приводит ли это к ошибкам (отсутствию ожидаемых атрибутов).