Наследование и полиморфизм
Наследование позволяет создавать новый класс на основе существующего, а полиморфизм — применять один и тот же вызов к разным объектам. Рассмотрим оба принципа на примерах Python.
Список тем (2 из 2)
Наследование — создание нового класса на основе существующего: производный класс получает атрибуты и методы базового класса и добавляет собственные возможности. Это выражает отношение «A — разновидность B» (is-a): собака — разновидность животного, круг — разновидность фигуры. Код не дублируется: общая часть записывается в базовом классе один раз.
В Python базовый класс указывается в скобках: class Dog(Animal):. В конструкторе производного класса нужно вызвать конструктор базового с помощью super().__init__(name), чтобы установились общие атрибуты. Если производный класс записывает метод базового класса заново под тем же именем, это называется переопределением (override): метод speak() в Dog даёт результат, отличный от метода в Animal.
Полиморфизм («многоформие») — это способность одного и того же вызова работать по-разному в зависимости от типа объекта. Например, для списка объектов Dog и Cat цикл for a in animals: a.speak() выполняет для каждого объекта его собственный метод speak(), и цикл менять не нужно. Поэтому при добавлении нового класса существующий код продолжает работать без изменений. В Python подходит любой объект с нужным методом, даже если у классов нет общего базового класса (утиная типизация).
Перед использованием наследования проверьте отношение: верно ли сказать «производный класс — разновидность базового»? Если отношение другое — «имеет» (has-a), например у машины есть двигатель, — выбирают не наследование, а композицию: один объект хранится внутри другого. Принадлежность классу проверяет функция isinstance(d, Animal): для объекта d класса Dog она возвращает True.
Главное
- Наследование передаёт производному классу атрибуты и методы базового и уменьшает дублирование кода.
- Наследование применяют при отношении «is-a» (является разновидностью); при «has-a» (имеет) выбирают композицию.
- В конструкторе производного класса
super().__init__(...)настраивает базовый класс. - Переопределение (override) метода меняет поведение в производном классе.
- Полиморфизм обеспечивает разное выполнение одного и того же вызова в зависимости от типа объекта.
Практические задания
- Напишите базовый класс
Animal(атрибутname, методspeak()) и наследующие от него классыDogиCat; пусть каждый по-своему переопределяетspeak(). Заставьте «говорить» список животных одним циклом. - Создайте базовый класс
Shapeи производныеCircle(радиусr) иRectangle(w,h); реализуйте в каждом методarea(), вычисляющий площадь, и найдите общую площадь списка разных фигур. - Пусть класс
Carхранит объектEngineкак композицию (self.engine = Engine()); письменно объясните, почему здесь правильный выбор — композиция, а не наследование.
Вопросы для закрепления
Проверьте себя: сначала подумайте, потом откройте ответ.
1В каком случае вместо наследования выбирают композицию?Показать ответСкрыть ответ
Когда отношение между классами — «имеет» (has-a), например у машины есть двигатель, а не «является разновидностью» (is-a).2Что такое переопределение метода (override)?Показать ответСкрыть ответ
Повторная реализация метода базового класса в производном классе под тем же именем.3Как полиморфизм упрощает код?Показать ответСкрыть ответ
Один и тот же вызов применяется к объектам разных классов, поэтому при добавлении нового типа не нужно менять цепочки условий `if`.
Войдите на сайт
Слайды и PDF доступны только зарегистрированным пользователям: и просмотр, и скачивание. Вход бесплатный.
Войдите на сайт
Слайды и PDF доступны только зарегистрированным пользователям: и просмотр, и скачивание. Вход бесплатный.
Пройдено тем: 0 из 2
Войти и отметить