logo search
Объектно-ориентированное программирование и C++

3.3 Наследование

Одной из самых восхитительных особенностей живой природы является ее способность порождать потомство, обладающее характеристиками, сходными с характеристиками предыдущего поколения. Заимствованная у природы идея наследования решает проблему модификации поведения объектов и придает ООП исключительную силу и гибкость. Наследование позволяет, практически без ограничений, последовательно строить и расширять классы, созданные вами или кем-то еще. Начиная с самых простых классов, можно создавать производные классы по возрастающей сложности, которые не только легки в отладке, но и просты по внутренней структуре.

Последовательное проведение в жизнь принципа наследования, особенно при разработке крупных программных проектов, хорошо согласуется с техникой нисходящего структурного программирования (от общего к частному), и во многом стимулирует такой подход. При этом сложность кода программы в целом существенно сокращается. Производный класс (потомок) наследует все свойства, методы и события своего базового класса (родителя) и всех его предшественников в иерархии классов.

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

Кроме того, производный класс может перегружать (overload) наследуемые методы в том случае, когда их работа в базовом классе не подходит потомку. Использование перегрузки в ООП всячески поощряется, хотя в прямом понимании значения этого слова перегрузок обычно избегают. Говорят, что метод перегружен, если он ассоциируется с более чем одной одноименной функцией. Обратите внимание, что механизм вызовов перегруженных методов в иерархии классов полностью отличается от вызовов переопределенных функций. Перегрузка и переопределение - это разные понятия. Виртуальные методы используются для переопределения функций базового класса.

Чтобы применить концепцию наследования, к примеру, с часами, положим, что следуя принципу наследования, фирма "Casio" решила выпустить новую модель, дополнительно способную, скажем, произносить время при двойном нажатии любой из существующих кнопок. Вместо того, чтобы проектировать заново модель говорящих часов (новый класс, в терминологии ООП), инженеры начнут с ее прототипа (произведут нового потомка базового класса, в терминологии ООП). Производный объект унаследует все атрибуты и функциональность родителя. Произносимые синтезированным голосом цифры станут новыми членами данных потомка, а объектные методы кнопок должны быть перегружены, чтобы реализовать их дополнительную функциональность. Реакцией на событие двойного нажатия кнопки станет новый метод, который реализует произнесение последовательности цифр (новых членов данных), соответствующей текущему времени. Все вышесказанное в полной мере относится к программной реализации говорящих часов.