Простое наследование | это… Что такое Простое наследование?
Насле́дование — один из четырёх важнейших механизмов объектно-ориентированного программирования (наряду с инкапсуляцией, полиморфизмом и абстракцией), позволяющий описать новый класс на основе уже существующего (родительского), при этом свойства и функциональность родительского класса заимствуются новым классом.
Другими словами, класс-наследник реализует спецификацию уже существующего класса (базовый класс). Это позволяет обращаться с объектами класса-наследника точно так же, как с объектами базового класса [1].
Содержание
|
Типы наследования
Простое наследование
Класс, от которого произошло наследование, называется
В некоторых языках используются абстрактные классы. Абстрактный класс — это класс, содержащий хотя бы один абстрактный метод, он описан в программе, имеет поля, методы и не может использоваться для непосредственного создания объекта. То есть от абстрактного класса можно только наследовать. Объекты создаются только на основе производных классов, наследованных от абстрактного. Например, абстрактным классом может быть базовый класс «сотрудник ВУЗа», от которого наследуются классы «аспирант», «профессор» и т. д. Так как производные классы имеют общие поля и функции (например, поле «год рождения»), то эти члены класса могут быть описаны в базовом классе. В программе создаются объекты на основе классов «аспирант», «профессор», но нет смысла создавать объект на основе класса «сотрудник вуза».
Множественное наследование
При множественном наследовании у класса может быть более одного предка. В этом случае класс наследует методы всех предков. Достоинства такого подхода в большей гибкости. Множественное наследование реализовано в C++. Из других языков, предоставляющих эту возможность, можно отметить Эйфель. Множественное наследование поддерживается в языке Java, C# и др.), от множественного наследования было решено отказаться в пользу интерфейсов. Практически всегда можно обойтись без использования данного механизма. Однако, если такая необходимость все-таки возникла, то, для разрешения конфликтов использования наследованных методов с одинаковыми именами, возможно, например, применить операцию расширения видимости — «::» — для вызова конкретного метода конкретного родителя.
Попытка решения проблемы наличия одинаковых имен методов в предках была предпринята в языке Эйфель, в котором при описании нового класса необходимо явно указывать импортируемые члены каждого из наследуемых классов и их именование в дочернем классе.
Большинство современных объектно-ориентированных языков программирования (C#, Delphi и др. ) поддерживает возможность одновременно наследоваться от класса-предка и реализовать методы нескольких интерфейсов одним и тем же классом. Этот механизм позволяет во многом заменить множественное наследование — методы интерфейсов необходимо переопределять явно, что исключает ошибки при наследовании функциональности одинаковых методов различных классов-предков.
Наследование в языке C++
«Наследование» в C++:
class A{ //базовый класс }; class B : public A{ //public наследование } class C : protected A{ //protected наследование } class Z : private A{ //private наследование }
В C++ существует три типа наследования: public, protected, private. Спецификаторы доступа членов базового класса меняются в потомках следующим образом:
- при public-наследовании все спецификаторы остаются без изменения.
- при protected-наследовании все спецификаторы остаются без изменения, кроме спецификатора public, который меняется на спецификатор protected (то есть public-члены базового класса в потомках становятся protected).
- при private-наследовании все спецификаторы меняются на private.
Одним из основных преимуществ public-наследования является то, что указатель на классы—наследники может быть неявно преобразован в указатель на базовый класс, то есть для примера выше можно написать:
A* a = new B;
Эта интересная особенность открывает возможность динамической идентификации типа (RTTI).
Наследование в языке Delphi
Для использования механизма наследования в class указать класс предок:
Предок:
TAncestor = class private protected public //Виртуальная процедура. procedure VirtualProcedure; virtual; abstract; procedure StaticProcedure; end;
Наследник:
TDescendant = class(TAncestor) private protected public //Перекрытие виртуальной процедуры. procedure VirtualProcedure; override; procedure StaticProcedure; end;
Абсолютно все классы в TObject.
Наследование в языке Python
[2](англ. method resolution order).
class Ancestor1(object): # Предок 1 def m1(self): pass class Ancestor2(object): # Предок 2 def m1(self): pass class Descendant(Ancestor1, Ancestor2): # Наследник def m2(self): pass d = Descendant() # инстанциация print d.__class__.__mro__ # порядок разрешения метода:
(<class '__main__.Descendant'>, <class '__main__.Ancestor1'>, <class '__main__.Ancestor2'>, <type 'object'>)
С версии object. «Классические» классы будут поддерживаться вплоть до версии 2.6, но удалены из языка в Python версии 3.0.
Множественное наследование применяется в Питоне, в частности, для введения в основной класс классов-примесей (mix-in).
Примечания
- ↑ http://www.citforum.ru/database/articles/grigoriev/
- ↑ о порядке разрешения метода в Python
См. также
- Абстракция данных
- Инкапсуляция (программирование)
- Полиморфизм в языках программирования
- Виртуальное_наследование
Ссылки
- Multiple Inheritance
Дочерние классы C++
В языке программирования существует концепция наследования, используемая для создания родительско-дочерних отношений между различными классами. Когда происходит наследование, появляются дочерние классы. Термин «дочерний класс» означает, что он наследует некоторые свойства родительского класса, т.е. Базового класса. Здесь вы должны понимать, что классы C ++ инициализируются своим объектом. При наследовании будут созданы только объекты дочернего класса, но не родительский класс. Объект дочернего класса будет использоваться для выполнения или запуска родительского класса вместе с его классом.
Содержание
- Метод 1: простое / одиночное наследование
- Метод 2: множественное наследование
- Метод 3: многоуровневое наследование
- Метод 4: Иерархическое наследование
- Метод 5: наследование гибридного / многолучевого распространения
- Заключение
Метод 1: простое / одиночное наследование
Мы начнем с одинарного наследования. Он содержит один единственный дочерний класс, который будет производным от единственного родительского класса. Итак, откройте терминал оболочки, используя «Ctrl + Alt + T». Убедитесь, что компилятор C ++ уже настроен в вашей системе Ubuntu 20.04. Используйте ключевое слово «touch», чтобы создать новый файл C ++ с именем «child.cc». После создания файла откройте его в редакторе, чтобы отредактировать. Мы использовали редактор Nano, чтобы открывать его прямо в редакторе терминала. Вы также можете использовать Vim или текстовый редактор. Обе команды для создания и открытия файла C ++ перечислены и показаны на следующем снимке экрана:
Мы добавили поток ввода-вывода в его начало. После этого был добавлен еще один стандартный заголовок C ++. После файла заголовка мы использовали стандартное пространство имен для использования операторов ввода-вывода в коде. Мы объявили родительский класс с именем «A» с единственной переменной целочисленного типа «ida», и к нему можно получить доступ где угодно в других классах, поскольку он является общедоступным. Другой класс с именем «B» был объявлен как дочерний класс, поскольку он наследует класс «A» с использованием знака «:». Оба класса здесь публичные. Дочерний класс «B» также содержит общедоступный член данных целочисленного типа с именем «idb». Затем был инициализирован основной метод. Он содержит инициализацию объекта дочернего класса «b».
Следует отметить, что в рамках наследования нет необходимости создавать объект родительского класса, если у него есть дочерний класс, наследующий его. Объект дочернего класса «b» использовался для инициализации и отображения членов общедоступных данных родительского и дочернего классов, как показано на изображении ниже. Сохраните этот код и выйдите из файла с помощью «Ctrl + S» и «Ctrl + X»:
Скомпилируйте код C ++ с помощью компилятора GCC в оболочке. Компиляция прошла успешно. После выполнения у нас есть результат в виде идентификатора родительского класса и идентификатора дочернего класса:
Метод 2: множественное наследование
Начнем с примера множественного наследования. Снова откройте файл кода «child.cc» в редакторе Nano. Заголовочные файлы и стандартное пространство имен остались без изменений. Мы объявили два родительских класса A и B, каждый из которых содержит конструктор, то есть A () и B (). Оба конструктора содержат стандартный оператор cout, используемый для вывода на печать, и сообщают нам, в каком классе мы сейчас находимся. Был объявлен дочерний класс C, который наследует оба родительских класса A и B, используя знак «:». Этот класс не содержит никакой реализации. После инициализации и объявления класса мы использовали основной метод. Функция main () содержит инициализацию объектов дочернего класса C, то есть «obj». После создания этого объекта оба конструктора родительских классов, то есть A и B, будут выполнены автоматически.
Таким образом, оба оператора cout в функциях конструктора будут распечатаны в оболочке. Сохраните обновленный код и вернитесь в оболочку, нажав клавиши Ctrl + S и Ctrl + X:
Компиляция этого кода не вызывает исключения; следовательно, ошибок пока не обнаружено. Выполнение показывает результат, как и ожидалось. Оба оператора печати были отображены в оболочке, то есть оператор cout родительского класса A и B:
Метод 3: многоуровневое наследование
При таком наследовании один дочерний класс будет производным и будет использовать другой класс как дочерний класс. Итак, мы открыли тот же файл кода в редакторе Nano. Заголовочные файлы оставлены без изменений. Мы объявили три класса, то есть A, B и C. Класс C является дочерним классом родительского класса B, а класс B является дочерним классом родительского класса A. Только класс A не унаследован от любого другого класса.. Все три класса содержат конструкторы, использующие оператор cout для отображения соответствующего сообщения в оболочке в соответствии с их классом. Создан объект класса C, который выполнит конструктор своего родительского класса B и, в конечном итоге, выполнит конструктор родительского класса A:
После компиляции и выполнения мы выполнили все операторы cout в конструкторах трех классов с одним объектом дочернего класса C, например obj:
Метод 4: Иерархическое наследование
Наследование можно назвать иерархическим, если несколько дочерних классов являются производными от одного класса. Итак, мы немного обновили код. Дочерние классы B и C являются производными от родительского класса A из кода изображения ниже. Поскольку есть два дочерних класса, есть и два объекта. Объект «objb» относится к дочернему классу B и запускает конструктор как родительского класса A, так и дочернего класса B. Объект «objc» является дочерним классом C, выполняющим оба конструктора родительского класса A и дочернего класса B. Итак, родительский конструктор здесь выполнялся два раза:
После запуска обновленного файла мы получаем ожидаемый результат в виде 4 строк: