17.1 – Введение в наследование
В предыдущей главе мы обсуждали композицию объектов, в которой сложные классы конструируются из более простых классов и типов. Композиция объектов идеальна для создания новых объектов, имеющих со своими компонентами связи «имеет что-либо». Однако композиция объектов – это лишь один из двух основных способов, с помощью которых C++ позволяет создавать сложные классы. Второй способ – через наследование, которое моделирует между двумя объектами связь «является чем-либо».
В отличие от композиции объектов, которая выполняет создание новых объектов путем комбинирования и соединения других объектов, наследование выполняет создание новых объектов путем прямого получения атрибутов и поведения других объектов, а затем их расширения или специализации. Как и композиция объектов, в реальной жизни наследование присутствует везде. Когда вы были зачаты, вы унаследовали гены своих родителей и приобрели физические свойства от них обоих, но затем сверху вы добавили свою личность. Технологические продукты (компьютеры, сотовые телефоны и т.д.) наследуют функции своих предшественников (часто используемые для обратной совместимости). Например, процессор Intel Pentium унаследовал многие функции, определенные процессором Intel 486, который сам унаследовал функции от более ранних процессоров. C++ унаследовал многие функции от C, языка, на котором он основан, а C унаследовал многие из своих функций от языков программирования, которые были до него.
Рассмотрим яблоки и бананы. Хотя яблоки и бананы – это разные фрукты, их объединяет то, что они являются фруктами. А поскольку яблоки и бананы – это фрукты, простая логика подсказывает нам, что всё, что верно в отношении фруктов, также верно в отношении яблок и бананов. Например, у всех фруктов есть название, цвет и размер. Следовательно, у яблок и бананов также есть название, цвет и размер. Мы можем сказать, что яблоки и бананы наследуют (приобретают) все эти свойства фруктов, потому что они являются фруктами. Мы также знаем, что фрукты подвергаются процессу созревания, в результате чего они становятся съедобными. Поскольку яблоки и бананы – это фрукты, мы также знаем, что яблоки и бананы наследуют процесс созревания.
Диаграмма связей между яблоками, бананами и фруктами может выглядеть примерно так:
Эта диаграмма определяет иерархию.
Иерархии
Иерархия – это диаграмма, которая показывает, как связаны различные объекты. Большинство иерархий либо демонстрируют прогрессию во времени (386 → 486 → Pentium), либо классифицируют вещи таким образом, чтобы переходить от общего к частному (фрукты → яблоко → Ред Делишес). Если вы когда-нибудь изучали биологию, то знаменитая систематика (царство, отдел, класс, порядок, семейство, род и вид) определяет иерархию (от общего к частному).
Вот еще один пример иерархии: квадрат – это прямоугольник, который является четырехугольником, а четырехугольник – это фигура. Прямоугольный треугольник – это треугольник, который также является фигурой. Если поместить эту иерархию на диаграмму, то она будет выглядеть так:
Эта диаграмма идет от общего (вверху) к частному (внизу), при этом каждый элемент в иерархии наследует свойства и поведение элемента над ним.
Взгляд в будущее
В этой главе мы рассмотрим основы работы наследования в C++.
В следующей главе мы рассмотрим, как наследование делает возможным полиморфизм (одно из самых модных словечек объектно-ориентированного программирования) через виртуальные функции.
По мере продвижения мы также будем говорить о ключевых преимуществах наследования, а также о некоторых недостатках.