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