Наследование в программировании: определение, виды, описание и отличия
Наследование классов в программировании свойственно объектно-ориентированным языкам, например С. Наследование входит в основные принципы ООП и стоит рядом с такими принципами, как:
абстракция,
инкапсуляция,
полиморфизм.
Абстракция — это процесс придания объекту уникальных характеристик, которые выделяют его среди других объектов, подчеркивая его концепцию и основные свойства.
Инкапсуляция — это подход в ООП, который позволяет программисту взаимодействовать с программным компонентом, не задумываясь о том, что у него внутри, а также наладить этому компоненту защиту при помощи публичных методов.
Полиморфизм — это способность объектов с одинаковой спецификой по-разному реализовываться.
Подробнее на каждом принципе мы остановимся в следующих статьях. А сегодня расскажем, что такое наследование в ООП. Наследование классов в ООП (объектно-ориентированном программировании)
Наследование в программировании — это возможность описать новый класс объекта на основе уже существующего. При таком подходе наследующий класс «перенимает» специфику родительского класса и использует ее по собственному назначению.
Другими словами, наследование помогает повторно использовать уже написанный код для определенного класса. Использование наследования образует иерархию классов, где присутствуют:
родительские или базовые классы — это классы, от которых заимствовали характеристики и свойства;
потомственные или наследующие классы — это классы, которые получились на основе характеристик родительских классов.
Наследование может быть 2-х видов:
простое,
множественное.
Простое наследование классов в программировании
Простое наследование еще называется одиночным — это наследование, при котором создается «родство» между двумя классами. То есть один класс-потомок перенимает характеристики от одного родительского класса.
Даже если от одного родительского класса будет исходить несколько классов-потомков, это все равно будет простым наследованием. Простое наследование поддерживается большинством объектно-ориентированных языков, в отличие от множественного наследования.
Множественное наследование классов в программировании
Множественное наследование классов подразумевает ситуацию, когда один потомственный класс принимает характеристики от нескольких родительских классов. Такой подход помогает реализовывать очень гибкие и настраиваемые классы-потомки.
Его поддерживают не все ОО-языки. Например, множественное наследование поддерживают C, C++, Python, Eiffel, UML, но не поддерживают Java и C#. Некоторые языки отказались от множественного наследования, потому что оно является источником потенциальных ошибок из-за присутствия одинаковых имен у классов. Поэтому в таких языках было решено уйти от множественного наследования и заменить его интерфейсами.
Интерфейс — это подход в программировании, при котором определяются отношения между объектами, связанными похожими характеристиками. Такой подход довольно популярен в объектно-ориентированном программировании, так как исключает многие ошибки, возникающие в других подходах.
Наследование в программировании: реализация в языках
Давайте посмотрим, как реализуется наследование в некоторых языках программирования.
Наследование классов в С/С++ реализуется по следующему шаблону:
class Q {}; // Родительский класс
class W : public Q {}; // спецификатор Public
class E : protected Q {}; // спецификатор Protected
class R : private Q {}; // спецификатор Private
Как видно, в С/С++ наследование может быть организовано тремя спецификаторами.
Данные спецификаторы объявляются в родительском и потомственном классе. Разный спецификатор — разные отношения между этими классами. Данной теме мы посвятим отдельную статью.
Множественное наследование на Python происходит по следующему шаблону:
class FirstParent(object): # первый родительский класс
def m1(self): pass
class SecondParent(object): # второй родительский класс
def m1(self): pass
class Inheritor(FirstParent, SecondParent): # Потомственный класс с двумя родительскими
В PHP реализация наследования происходит по следующему шаблону:
class Inheritor extends Parent {
}
Важная особенность в PHP — родительский класс объявляется после потомственного класса, при этом обязательно использовать перед именем родительского класса ключевое слово «extends».
Заключение
Наследование классов в программировании — это возможность повторно использовать уже написанный код для какого-либо класса. А это существенно экономит время на разработку и отладку программы.
Наследование классов — это процесс, связанный с объектно-ориентированным программированием, однако в разных ОО-языках он реализован по-разному. Например, множественное наследование поддерживают не все объектно-ориентированные языки.
Наследование. Урок 4 курса «Объектно-ориентированное программирование на Python»
Наследование – важная составляющая объектно-ориентированного программирования. Так или иначе мы уже сталкивались с ним, ведь объекты наследуют атрибуты своих классов. Однако обычно под наследованием в ООП понимается наличие классов и подклассов. Также их называют супер- или надклассами и классами, а также родительскими и дочерними классами.
Суть наследования здесь схожа с наследованием объектами от классов.
Дочерние классы наследуют атрибуты родительских, а также могут переопределять атрибуты и добавлять свои.
Простое наследование методов родительского класса
В качестве примера рассмотрим два класса столов. Класс Table – родительский по отношению к DeskTable (письменные столы). Независимо от своего типа все столы имеют длину, ширину и высоту. Пусть для письменных столов также важна площадь поверхности. Общее вынесем в класс, частное – в подкласс.
Наследственная связь между классами устанавливается через подкласс. При определении дочернего после его имени в скобках указывается родительский.
class Table:
def __init__(self, l, w, h):
self.length = l
self.width = w
self.height = h
class DeskTable(Table):
def square(self):
return self.width * self.length
t1 = Table(1.5, 1.8, 0.75)
t2 = DeskTable(0.8, 0.6, 0.7)
print(t2.square()) # вывод: 0.48В данном случае у класса DeskTable нет своего конструктора, поэтому он наследует его от родителя.
При создании объектов передавать аргументы необходимо в обоих случаях. Попытка вызова DeskTable с пустыми скобками приведет к ошибке.
С другой стороны, экземпляры надкласса Table, согласно неким родственным связям, не наследуют метод square своего подкласса.
В этом смысле терминология «родительский и дочерний класс» не совсем верна. Наследование в ООП – это скорее аналог систематизации и классификации наподобие той, что есть в живой природе. Все млекопитающие имеют четырехкамерное сердце, но только носороги – рог.
Полное переопределение метода надкласса
Рассмотрим вариант программы с «цепочкой наследования». Пусть дочерний по отношению к Table класс DeskTable в свою очередь выступит родительским по отношению к ComputerTable (компьютерные столы):
class Table:
def __init__(self, l, w, h):
self.length = l
self.width = w
self.height = h
class DeskTable(Table):
def square(self):
return self.width * self.length
class ComputerTable(DeskTable):
def square(self, monitor=0.
0):
return self.width * self.length - monitor
t3 = ComputerTable(0.8, 0.6, 0.7)
print(t3.square(0.3)) # вывод: 0.18Допустим, по задумке разработчиков рабочая поверхность компьютерного стола может вычисляться за вычетом площади, которую занимает монитор. В результате метод square в ComputerTable имеет отличия.
Определив в дочернем классе метод, одноименный методу родительского, мы тем самым переопределяем метод родительского класса. При вызове square на экземпляры ComputerTable будет вызываться метод из этого класса, а не из родительского класса DeskTable.
В то же время ComputerTable наследует конструктор класса от своей «бабушки» – класса Table.
Дополнение, оно же расширение, метода
Часто требуется не столько заменить, то есть полностью переопределить, метод родительского класса в дочернем, сколько дополнить, то есть расширить, код метода родительского класса в дочернем. В таких случаях решением является вызов метода надкласса в теле соответствующего метода подкласса.
Пусть имеется подкласс кухонных столов, для которых необходимо еще одно поле – количество посадочных мест. Из-за этой детали мы вынуждены в дочернем классе переопределить конструктор родительского.
class Table:
def __init__(self, l, w, h):
self.length = l
self.width = w
self.height = h
class KitchenTable(Table):
def __init__(self, l, w, h, p):
self.length = l
self.width = w
self.height = h
self.places = p
t4 = KitchenTable(1.5, 2, 0.75, 6)Поскольку существенная часть кода конструктора подкласса является такой же как в надклассе, правильнее будет вызвать метод другого класса, а не дублировать код:
class Table:
def __init__(self, l, w, h):
self.length = l
self.width = w
self.height = h
class KitchenTable(Table):
def __init__(self, l, w, h, p):
Table.__init__(self, l, w, h)
self.
places = p
t4 = KitchenTable(1.5, 2, 0.75, 6)Здесь в теле конструктора KitchenTable мы вызываем метод __init__ через объект-класс Table, а не через объект-экземпляр. Вспомним, что в таких случаях метод вызывается как обычная функция (объект, к которому применяется метод, не передается в качестве первого аргумента). Поэтому в конструктор надкласса мы «вручную» передаем текущий экземпляр (self), записывая его перед остальными аргументами.
У кода выше есть небольшой недостаток. Нам ничего не мешает (при условии совпадения количества параметров) вызвать конструктор другого класса, а не только родительского, указав его имя вместо Table. Кроме того, имя надкласса может измениться, и тогда есть риск неправильных обращений к нему из дочерних классов.
В Python c целью улучшения так называемой обслуживаемости кода можно использовать встроенную в язык функцию super. Наиболее распространенным вариантом ее применения является вызов метода родительского класса из метода подкласса:
class KitchenTable(Table):
def __init__(self, l, w, h, p):
super().
__init__(l, w, h)
self.places = pВ данном случае аргумент self в скобках вызываемого родительского метода указывать явно не требуется.
Параметры со значениями по умолчанию у родительского класса
Рассмотрим случай, когда родительский класс имеет параметры со значениями по умолчанию, а дочерний – нет:
class Table:
def __init__(self, l=1, w=1, h=1):
self.length = l
self.width = w
self.height = h
class KitchenTable(Table):
def __init__(self, p, l, w, h):
Table.__init__(self, l, w, h)
self.places = pПри таком определении классов можно создать экземпляр от Table без передачи аргументов для конструктора:
t = Table()
Можем ли мы создать экземпляр от KitchenTable, передав значение только для параметра p? Например, вот так:
k = KitchenTable(10)
Возможно ли, что p будет присвоено число 10, а l, w и h получат по единице от родительского класса? Невозможно, будет выброшено исключение по причине несоответствия количества переданных аргументов количеству требуемых конструктором:
... k = KitchenTable(10) TypeError: __init__() missing 3 required positional arguments: 'l', 'w', and 'h'
Когда создается объект от дочернего класса, сначала вызывается его конструктор, если он есть. Интерпретатор еще не знает, что в теле этого конструктора будет вызван конструктор родительского класса. Ведь это не обязательно. Значит, если все параметры дочернего конструктора не имеют значений по умолчанию, при построении объекта все значения должны передаваться.
Поэтому, если требуется допустить создание объектов от дочернего класса без передачи аргументов, придется назначить значения по умолчанию также в конструкторе дочернего класса.
class Table:
def __init__(self, l=1, w=1, h=1):
self.length = l
self.width = w
self.height = h
class KitchenTable(Table):
def __init__(self, l=1, w=1, h=0.7, p=4):
Table.__init__(self, l, w, h)
self.places = pПараметр p, которого нет у родительского класса, мы делаем последним не просто так.
Бывает, объекты разных родственных классов создаются или обрабатываются в одном цикле, то есть по одному алгоритму. При этом у них должны быть одинаковые «интерфейсы», то есть одинаковое количество передаваемых в конструктор аргументов.
Поэтому лучше, когда методы родственных классов принимают одинаковое число параметров. А если разное, то у «лишних» должны быть значения по-умолчанию, чтобы при вызове конструктора их можно было бы не передавать. Если такие параметры находятся еще и в конце, передачу аргументов для предстоящих параметров можно выполнять без ключей.
Другой вариант – отказаться от конструктора в дочернем классе, а значение для поля places устанавливать отдельным вызовом метода:
class Table:
def __init__(self, l=1, w=1, h=1):
self.length = l
self.width = w
self.height = h
class KitchenTable(Table):
places = 4
def set_places(self, p):
self.places = pЗдесь у всех кухонных столов по-умолчанию будет 4 места.
Если мы хотим изменить значение поля places, можем вызвать метод set_places(). Хотя в случае Python можем сделать это напрямую, присвоив полю. При этом у экземпляра появится собственное поле places.
k = KitchenTable() k.places = 6
Поэтому метод set_places() в общем-то не нужен.
В любом случае произвольное количество мест будет устанавливаться не в конструкторе, а отдельно. Если все же требуется указывать места при создании объекта, это можно сделать и в конструкторе родителя:
class Table:
def __init__(self, l=1, w=1, h=1):
self.length = l
self.width = w
self.height = h
if isinstance(self, KitchenTable):
p = int(input("Сколько мест: "))
self.places = pС помощью функции isinstance() проверяется, что создаваемый объект имеет тип KitchenTable. Если это так, то у него появляется поле places.
Мы не используем параметр p со значением по умолчанию в заголовке конструктора потому, что, если объектам других родственных классов он не нужен, не происходило путаницы и сложностей с документированием кода.
Практическая работа
Разработайте программу по следующему описанию.
В некой игре-стратегии есть солдаты и герои. У всех есть свойство, содержащее уникальный номер объекта, и свойство, в котором хранится принадлежность команде. У солдат есть метод «иду за героем», который в качестве аргумента принимает объект типа «герой». У героев есть метод увеличения собственного уровня.
В основной ветке программы создается по одному герою для каждой команды. В цикле генерируются объекты-солдаты. Их принадлежность команде определяется случайно. Солдаты разных команд добавляются в разные списки.
Измеряется длина списков солдат противоборствующих команд и выводится на экран. У героя, принадлежащего команде с более длинным списком, увеличивается уровень.
Отправьте одного из солдат первого героя следовать за ним. Выведите на экран идентификационные номера этих двух юнитов.
Курс с примерами решений практических работ:
pdf-версия, android-приложение
Наследование в объектно-ориентированном программировании
Химанши Сингх —
Опубликовано 26 октября 2020 г.
и изменено 14 июня 2022 г.
Новичок Программирование питон Техника
Обзор
- Узнайте о наследовании в объектно-ориентированном программировании и различных формах наследования
- Понимание переопределения методов и функции super() в мире объектно-ориентированного программирования
Введение
Наследование — один из наиболее важных аспектов объектно-ориентированного программирования (ООП). Ключ к пониманию наследования заключается в том, что оно обеспечивает возможность повторного использования кода. Вместо написания одного и того же кода снова и снова мы можем просто наследовать свойства одного класса в другой.
Как вы понимаете, это экономит массу времени. А в науке о данных время — деньги!
ООП — это объекты реального мира, а наследование — это способ представления реальных отношений. Вот пример — автомобиль, автобус, велосипед — все они относятся к более широкой категории под названием Транспортное средство .
Это означает, что они унаследовали свойства транспортных средств класса, т.е. все они используются для перевозки.
Мы можем представить эту связь в коде с помощью наследования.
Еще одна интригующая особенность наследования заключается в том, что оно носит транзитивный характер. Но что это значит? Мы увидим подробно позже в этой статье. Python также поддерживает различные типы наследования, о которых я подробно расскажу в этой статье.
Это вторая статья из серии статей, посвященных объектно-ориентированному программированию. Ознакомьтесь также с первой статьей:
- Основные концепции объектно-ориентированного программирования.
Содержание
- Что такое наследование в объектно-ориентированном программировании?
- Различные формы наследования в объектно-ориентированном программировании
- Одиночное наследство
- Множественное наследование
- Многоуровневое наследование
- Иерархическое наследование
- Гибридное наследие
- Переопределение метода
- Функция super()
Что такое наследование в объектно-ориентированном программировании?
Наследование — это процедура, при которой один класс наследует атрибуты и методы другого класса.
Класс, свойства и методы которого наследуются, называется родительским классом. И класс, который наследует свойства от родительского класса, является дочерним классом.
Интересно, что наряду с унаследованными свойствами и методами у дочернего класса могут быть свои собственные свойства и методы.
Вы можете использовать следующий синтаксис:\ для реализации наследования в Python:
класс parent_class: тело родительского класса класс дочерний_класс (родительский_класс): тело дочернего класса
Давайте посмотрим на реализацию:
Код Python:
Мы создали два дочерних класса, а именно «BMW» и «Audi», которые унаследовали методы и свойства родительского класса «Car». Мы не предоставили никаких дополнительных функций и методов в классе BMW. В то время как внутри класса Audi есть еще один метод.
Обратите внимание, что метод экземпляра description() родительского класса доступен объектам дочерних классов с помощью obj1.
description() и obj2.description(). И отдельный метод класса Audi также доступен с помощью obj2.audi_desc().
Мы можем проверить базовый или родительский класс любого класса, используя встроенный атрибут класса __bases__
печать(BMW.__базы__, Audi.__базы__)
Как мы видим, базовым классом обоих подклассов является Автомобиль. Теперь давайте посмотрим, что происходит при использовании __base__ с родительским классом Car:
печать(автомобиль.__базы__)
Всякий раз, когда мы создаем новый класс в Python 3.x, он наследуется от встроенного базового класса с именем Object. Другими словами, класс Object является корнем всех классов.
Формы наследования в объектно-ориентированном программировании
В целом существует пять форм наследования, основанных на участии родительского и дочернего классов.
1. Одиночное наследование
Это форма наследования, при которой класс наследует только один родительский класс.
Это простая форма наследования, поэтому ее также называют простым наследованием .
класс Родитель:
защита f1(я):
print("Функция родительского класса.")
класс Ребенок (Родитель):
защита f2(я):
print("Функция дочернего класса")
объект1 = Ребенок()
объект1.f1()
объект1.f2() Здесь класс Child наследует только один класс Parent, следовательно, это пример одиночного наследования.
2. Множественное наследование
Наследование становится множественным наследованием, когда класс наследует более одного родительского класса. Дочерний класс после наследования свойств от различных родительских классов имеет доступ ко всем их объектам.
класс Parent_1:
защита f1(я):
print("Функция класса parent_1.")
класс Parent_2:
защита f2(я):
print("Функция класса parent_2.")
класс Parent_3:
защита f3(я):
print("функция класса parent_3.")
класс Ребенок (Родитель_1, Родитель_2, Родитель_3):
защита f4(я):
print("Функция дочернего класса")
object_1 = Ребенок()
объект_1.
f1()
объект_1.f2()
объект_1.f3()
объект_1.f4() Здесь у нас есть один дочерний класс, который наследует свойства трех родительских классов Parent_1, Parent_2 и Parent_3. Все классы имеют разные функции, и все функции вызываются с использованием объекта класса Child.
Но предположим, что дочерний класс наследует два класса, выполняющих одну и ту же функцию:
класс Parent_1:
защита f1(я):
print("Функция класса parent_1.")
класс Parent_2:
защита f1(я):
print("Функция класса parent_2.")
класс Ребенок (Родитель_1, Родитель_2):
защита f2(я):
print("Функция дочернего класса")
Здесь классы Parent_1 и Parent_2 имеют одинаковую функцию f1(). Теперь, когда объект класса Child вызывает f1(), поскольку класс Child наследует оба родительских класса, что, по вашему мнению, должно произойти?
объект = Ребенок() объект.f1()
Но почему не унаследована функция f1() класса Parent_2?
При множественном наследовании дочерний класс сначала ищет метод в своем собственном классе.
Если не найдено, то ищет в родительских классах depth_first и в порядке слева-направо. Поскольку это был простой пример всего с двумя родительскими классами, мы ясно видим, что класс Parent_1 был унаследован первым, поэтому дочерний класс будет искать метод в классе Parent_1 перед поиском в классе Parent_2.
Но для сложных проблем наследования определить порядок становится сложно. Таким образом, фактический способ сделать это называется Порядок разрешения методов (MRO) в Python. Мы можем найти MRO любого класса, используя атрибут __mro__
Ребенок.__мро__
Это говорит о том, что класс Child сначала посетил класс Parent_1, а затем Parent_2, поэтому будет вызван метод f1() класса Parent_1.
Возьмем немного сложный пример на Python:
класс Parent_1: проходить класс Parent_2: проходить класс Parent_3: проходить класс Child_1 (Parent_1,Parent_2): проходить класс Child_2 (Parent_2,Parent_3): проходить класс Child_3(Child_1,Child_2,Parent_3): пройти
Здесь класс Child_1 наследует два класса — Parent_1 и Parent_2.
Класс Child_2 также наследует два класса — Parent_2 и Parent_3. Другой класс Child_3 наследует три класса — Child_1, Child_2 и Parent_3.
Теперь, просто взглянув на это наследование, довольно сложно определить порядок разрешения методов для класса Child_3. Итак, вот фактическое использование __mro__-
Ребенок_3.__мро__
Мы видим, что сначала интерпретатор ищет Child_3, затем Child_1, затем Parent_1, Child_2, Parent_2 и Parent_3 соответственно.
3. Многоуровневое наследование
Например, класс_1 наследуется классом_2, а этот класс_2 также наследуется классом_3, и этот процесс продолжается. Это известно как многоуровневое наследование. Давайте разберемся на примере:
Родительский класс:
защита f1(я):
print("Функция родительского класса.")
класс Child_1 (родитель):
защита f2(я):
print("Функция класса child_1.")
класс Child_2(Child_1):
защита f3(я):
print("Функция класса child_2.
")
obj_1 = Ребенок_1()
obj_2 = Ребенок_2()
obj_1.f1()
obj_1.f2()
печать("\n")
obj_2.f1()
obj_2.f2()
obj_2.f3() Здесь класс Child_1 наследует класс Parent, а класс Child_2 наследует класс Child_1. При этом Child_1 имеет доступ к функциям f1() и f2(), тогда как Child_2 имеет доступ к функциям f1(), f2() и f3(). Если мы попытаемся обратиться к функции f3() с помощью объекта класса Class_1, то возникнет ошибка следующего содержания:
Объект «Ребенок_1» не имеет атрибута «f3»
obj_1.f3()
4- Иерархическое наследование
При этом различные дочерние классы наследуют один родительский класс. Пример, приведенный во введении к наследованию, является примером иерархического наследования, поскольку классы BMW и Audi наследуют класс Car.
Для простоты рассмотрим другой пример:
Родительский класс:
deff1(я):
print("Функция родительского класса.")
класс Child_1 (родитель):
deff2(я):
print("Функция класса child_1.
")
класс Child_2 (родитель):
deff3(я):
print("Функция класса child_2.")
obj_1 = Ребенок_1()
obj_2 = Ребенок_2()
obj_1.f1()
obj_1.f2()
печать('\п')
obj_2.f1()
obj_2.f3() Здесь два дочерних класса наследуют один и тот же родительский класс. Класс Child_1 имеет доступ к функциям f1() класса Parent и функции f2() самого себя. Тогда как класс Child_2 имеет доступ к функциям f1() класса Parent и функции f3() самого себя.
5- Гибридное наследование
Сочетание нескольких форм наследования называется гибридным наследованием. После этого примера будет понятнее:
Родительский класс:
защита f1(я):
print("Функция родительского класса.")
класс Child_1 (родитель):
защита f2(я):
print("Функция класса child_1.")
класс Child_2 (родитель):
защита f3(я):
print("Функция класса child_2.")
класс Child_3 (Child_1, Child_2):
защита f4(я):
print("Функция класса child_3.")
объект = Ребенок_3()
объект.
f1()
объект.f2()
объект.f3()
объект.f4() В этом примере два класса «Дочерний_1» и «Дочерний_2» являются производными от базового класса «Родительский» с использованием иерархического наследования. Другой класс «Child_3» является производным от классов «Child_1» и «Child_2» с использованием множественного наследования. Класс «Child_3» теперь получен с использованием гибридного наследования.
Переопределение метода
Концепция переопределения очень важна в наследовании. Это дает особую возможность дочерним/подклассам предоставлять конкретную реализацию метода, который уже присутствует в их родительских классах.
Родительский класс:
защита f1(я):
print("Функция родительского класса")
класс Ребенок (Родитель):
защита f1(я):
print("Функция дочернего класса.")
объект = ребенок ()
obj.f1() Здесь функция f1() класса Child переопределяет функцию f1() класса Parent. Всякий раз, когда объект класса Child вызывает f1(), выполняется функция класса Child.
Однако объект родительского класса может вызывать функцию f1() родительского класса.
obj_2 = Родительский() obj_2.f1()
Функция super()
Функция super() в Python возвращает прокси-объект, который ссылается на родительский класс, используя ключевое слово super . Это ключевое слово super() в основном полезно для доступа к переопределенным методам родительского класса.
Официальная документация по функции super() содержит два основных варианта использования super():
- В иерархии классов с одиночным наследованием, super помогает ссылаться на родительские классы, не называя их явно, что делает код более удобным для сопровождения.
Пример-
Родительский класс: защита f1(я): print("Функция родительского класса") класс Ребенок (Родитель): защита f1(я): супер().f1() print("Функция дочернего класса.") объект = ребенок () obj.f1()Здесь с помощью super().
f1() был вызван метод f1() суперкласса дочернего класса, т.е. родительского класса, без явного указания его имени.Следует отметить, что класс super() может принимать два параметра: первый — это имя подкласса, а второй — объект, являющийся экземпляром этого подкласса. Посмотрим как-
Родительский класс: защита f1(я): print("Функция родительского класса") класс Ребенок (Родитель): защита f1(я): супер( Ребенок, я ).f1() print("Функция дочернего класса.") объект = ребенок () obj.f1()Первый параметр относится к подклассу Child , а второй параметр относится к объекту Child, который в данном случае равен self . Вы можете видеть, что результат после использования super() и super(Child, self) одинаков, потому что в Python 3 super(Child, self) эквивалентен self().
Теперь давайте рассмотрим еще один пример использования функции __init__.
класс Родительский (объект): def__init__(я, имя_родителя): print(ParentName, 'производный от другого класса.
')
класс Ребенок (Родитель):
def__init__(я, ChildName):
print(name,'является подклассом.')
super().__init__(Имя_ребенка)
obj = Ребенок('Ребенок') Здесь мы сделали то, что вызвали функцию __init__ класса Parent (внутри класса Child), используя super().__init__( ChildName ) . И поскольку метод __init__ класса Parent требует один аргумент, он был передан как «ChildName». Итак, после создания объекта класса Child сначала выполняется функция __init__ класса Child, а затем функция __init__ класса Parent.
- Второй вариант использования — поддержка совместного множественного наследования в динамической среде выполнения.
класс Первый(): защита __init__(сам): распечатать("первый") супер().__инит__() класс второй(): защита __init__(сам): распечатать("секунда") супер().__инит__() класс Третий (Второй, Первый): защита __init__(сам): распечатать("третий") супер().__инит__() obj = Third()
Вызов super() находит следующий метод в MRO на каждом шаге, поэтому First и Second тоже должны иметь его, иначе выполнение останавливается в конце первый().
__init__ .Обратите внимание, что суперклассом Первого и Второго является Объект .
Давайте также найдем MRO для Third()-
Third.__mro__
Порядок: Третий > Второй > Первый, и такой же порядок вывода.
End Notes
В заключение, в этой статье я развил концепцию наследования в объектно-ориентированном программировании на Python. Я рассмотрел различные формы наследования и некоторые общие концепции наследования, такие как переопределение метода и функция super().
Надеюсь, вы поняли принципы, изложенные в этой статье. Дайте мне знать в комментариях ниже, если у вас есть какие-либо вопросы.
переопределение метода наследования Объектно-ориентированное программированиефункция super()
Содержание
Шайвья Вашиштха говорит:
Отличная работа!! было действительно интересно и полезноВайбхав Караят говорит:
Довольно грамотный блог.
Спасибо.Химанши Сингх говорит:
Рад помочь!Химанши Сингх говорит:
Рад помочь!Лучшие ресурсы
Скачать приложение
Мы используем файлы cookie на веб-сайтах Analytics Vidhya для предоставления наших услуг, анализа веб-трафика и улучшения вашего опыта на сайте. Используя Analytics Vidhya, вы соглашаетесь с нашей Политикой конфиденциальности и Условиями использования. Принять
Политику конфиденциальности и использования файлов cookie
100+ вакансий в области обработки данных
Lenovo, TVS, Convergytics, Ripik.AI и многие другие нанимают | Открыто для всех энтузиастов науки о данных. Зарегистрируйтесь сейчасЧто такое наследование в программировании? Итак, наследование определяется как тенденция одного класса получать свойства и характеристики от других классов. Он предоставляет дополнительные функциональные возможности для извлечения функций из базового класса и значительного включения их в другие производные классы.

В компьютерном программировании наследование является важной концепцией парадигмы объектно-ориентированного программирования (ООП). Он предоставляет механизм для установления отношений и построения иерархий классов в составе объектов. Наследование означает использование предварительно написанного или созданного ранее кода. И нужно помнить одну вещь: мы просто используем код, а не обновляем или изменяем его. Функции и методы, определенные в одном классе, могут использоваться для управления другими элементами данных этого класса.
Понимание наследования
Чтобы понять наследование, нам нужно сосредоточиться на двух типах классов: подклассе и суперклассе .
Подкласс , , также известный как производный класс, это класс, который наследует свойство, а суперкласс также известен как базовый класс; это класс, от которого наследуются свойства. В некоторых случаях подкласс называется дочерним классом, а суперкласс известен как родительский класс.
Итак, до сих пор очевидно, что подкласс, то есть дочерний класс, наследует свойства суперкласса, то есть родительского класса.
Как наследование делает работу такой легкой?
В объектно-ориентированном программировании всякий раз, когда создается класс, назначаются элементы данных и функции данных. Члены данных — это те переменные, которые объявлены в одном и том же классе. Функции данных — это методы или функции, определенные в классе. Эти функции обычно используются для управления элементами данных. Эти функции данных и элементы данных могут быть общедоступными или частными, в зависимости от области использования.
Итак, с помощью наследования нам не нужно рекурсивно создавать и определять элементы данных и функции. Мы кодируем один раз в классе, и они могут наследовать все свойства элементов данных и функций в последующем подклассе. Эта функция также помогает в эффективном динамическом программировании.
Типы наследования:
- Одиночное наследование: Один производный класс наследуется от одного базового класса.

- Множественное наследование: Один производный класс наследуется от многих базовых классов.
- Многоуровневое наследование: Один производный класс наследуется от других производных классов.
- Иерархальное наследование: Более одного производного класса наследуются от одного базового класса.
- Наследование гибридов: Сочетание более чем одного типа наследования.
Что можно сделать с наследством?
Если команда работает над большой программой или фрагментом кода, наследование действует как благословение. Нам не нужно писать код повторно; если есть иерархия в классах или классах, которые зависят друг от друга, мы можем использовать код наследования от базового класса к дочернему классу. Это предотвратит повторное написание одного и того же кода. Наследование также играет важную роль в динамическом программировании. Один код можно использовать во многих областях, и, следовательно, сложность может быть уменьшена.
Если кто-то внесет изменения в один подкласс, это не повлияет на суперкласс или другие классы.
Преимущества наследования
Ниже перечислены некоторые плюсы наследования:
- Частое использование кода, написанного один раз, т. е. повторное использование кода.
- Один суперкласс может использоваться для количества подклассов в иерархии.
- Никаких изменений во всех базовых классах; просто делайте изменения только в родительском классе.
- Наследование используется для создания более доминирующих объектов.
- Наследование позволяет избежать дублирования и избыточности данных.
- Наследование используется, чтобы избежать пространственной и временной сложности.
Почему наследование важно в программировании?
Наследование важно в программировании из-за возможности повторного использования кода. Мы можем избежать дублирования данных и избыточности в нашей программе. Возьмем пример: если вы живете с родителями, то отец будет одним базовым классом, а вы (как ребенок) будете производным классом.
Таким образом, мы можем наследовать многие вещи, такие как фамилия, адресная строка, город и штат от родительского класса. Кроме того, если мы хотим обновить адрес или что-то еще, мы просто изменим адрес базового класса, и все производные классы унаследуют свойство этого базового класса.
Почему мы должны использовать наследование?
В первую очередь мы используем наследование для использования определенных частей кода и изменения определенных функций в соответствии с нашими потребностями, и это можно сделать без каких-либо сложностей. Наследование обеспечивает гибкость нашего кода для его повторного использования из базового класса в требуемый производный класс. Дочерний класс может переопределить свойства базового класса, не переписывая код в одном и том же классе снова и снова.
Зачем нам наследство?
- Чтобы повторно использовать код, напишите код и применяйте его дальше, где это необходимо.
- Во избежание дублирования и избыточности данных в программе.

- Чтобы уменьшить пространственную и временную сложность.
- Проще в парадигме иерархического программирования.
- Переменные с одним и тем же именем могут использоваться несколько раз в области действия кода.
- Для создания доминирующих объектов данных и функций.
Кто является подходящей аудиторией для изучения технологий наследования?
- Студенты факультета компьютерных наук.
- Студенты, изучающие программирование.
- Программист среднего уровня.
- выпускников информационных технологий.
- выпускников факультета электроники.
- Технический специалист, который занимается или хочет работать над иерархическим программированием.
Как эта технология поможет вам в карьерном росте?
Судя по обсуждению, технология наследования является важной частью объектно-ориентированного программирования, поэтому любой, кто хочет улучшить объектно-ориентированное программирование, должен иметь опыт работы с технологией наследования.



Некоторые языки отказались от множественного наследования, потому что оно является источником потенциальных ошибок из-за присутствия одинаковых имен у классов. Поэтому в таких языках было решено уйти от множественного наследования и заменить его интерфейсами.
Данные спецификаторы объявляются в родительском и потомственном классе. Разный спецификатор — разные отношения между этими классами. Данной теме мы посвятим отдельную статью.
0):
return self.width * self.length - monitor
t3 = ComputerTable(0.8, 0.6, 0.7)
print(t3.square(0.3)) # вывод: 0.18
__init__(l, w, h)
self.places = p
..
k = KitchenTable(10)
TypeError: __init__() missing 3 required
positional arguments: 'l', 'w', and 'h'
f1()
объект_1.f2()
объект_1.f3()
объект_1.f4()
")
obj_1 = Ребенок_1()
obj_2 = Ребенок_2()
obj_1.f1()
obj_1.f2()
печать("\n")
obj_2.f1()
obj_2.f2()
obj_2.f3()
")
класс Child_2 (родитель):
deff3(я):
print("Функция класса child_2.")
obj_1 = Ребенок_1()
obj_2 = Ребенок_2()
obj_1.f1()
obj_1.f2()
печать('\п')
obj_2.f1()
obj_2.f3()
f1()
объект.f2()
объект.f3()
объект.f4()
f1() был вызван метод f1() суперкласса дочернего класса, т.е. родительского класса, без явного указания его имени.
')
класс Ребенок (Родитель):
def__init__(я, ChildName):
print(name,'является подклассом.')
super().__init__(Имя_ребенка)
obj = Ребенок('Ребенок')
__init__ .
