Шаг 21.
Общие сведения о механизме наследования

    На этом шаге мы рассмотрим понятия, связанные с механизмом наследования.

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

    Каждый объект является конкретным представителем класса. Объекты одного класса имеют разные имена, но одинаковые по типам и внутренним именам данные. Объектам одного класса для обработки своих данных доступны одинаковые компонентные функции класса и одинаковые операции, настроенные на работу с объектами класса. Таким образом, класс выступает в роли типа, позволяющего вводить нужное количество объектов, имена (названия) которых программист выбирает по своему усмотрению.

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

    Иерархия классов позволяет определять новые классы на основе уже имеющихся. Имеющиеся классы обычно называют базовыми (иногда порождающими, родительскими), а новые классы, формируемые на основе базовых, - производными (порожденными), иногда классами-потомками, наследниками или дочерними классами. Производные классы "получают наследство" - данные и методы своих базовых классов - и, кроме того, могут пополняться собственными компонентами (данными и coбственными методами). Наследуемые компоненты не перемещаются в производный класс, а остаются в базовых классах. Сообщение, обработку которого не могут выполнить методы производного класса, автоматически передается в базовый класс. Если для обработки сообщения нужны данные, отсутствующие в производном классе, то их пытаются отыскать автоматически и незаметно для программиста в базовом классе (рисунок 1) .


Рис.1. Схема обработки сообщений в иерархии объектов (1 - обработка сообщений методами производного класса, 2 - обработка методами базового класса)

    Если класс "точка (позиция) на экране" считать базовым классом, то на его основе можно построить класс "окно на экране". Данными этого класса будут две точки:

Методы класса "окно на экране":

    Конструктор окна на экране:

    Деструктор окна на экране:

    Обратите внимание, что две точки по-разному используются в классе "окно на экране". Первая из них - это абсолютные координаты точки на экране, вторая - интерпретируется просто как пара чисел, определяющая размеры окна. Таким образом, если первая точка имеет координаты (4,3), а вторая (0,0), то это соответствует пустому окну (окну с нулевыми размерами). Наименьшее окно, в которое можно вывести один символ (или один пиксель в графическом режиме), должно иметь размеры (1,1) независимо от положения левого верхнего угла.

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

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

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

    В иерархии классов соглашение относительно доступности компонентов класса следующее.

    Собственные (private) методы и данные доступны только внутри того класса, где они определены.

    Защищенные (protected) компоненты доступны внутри класса, в котором они определены, и дополнительно доступны во всех производных классах.

    Общедоступные (public) компоненты класса видимы из любой точки программы, т.е. являются глобальными.

    Если считать, что объекты, т.е. конкретные представители классов, обмениваются сообщениями и обрабатывают их, используя методы и данные классов, то при обработке сообщения используются, во-первых, общедоступные члены всех классов программы; во-вторых, защищенные компоненты базовых и рассматриваемого классов и, наконец, собственные компоненты рассматриваемого класса. Собственные компоненты базовых и производных классов, а также защищенные компоненты производных классов недоступны для сообщения и не могут участвовать в его обработке.

    Еще раз отметим, что на доступность компонентов класса влияет не только явное использование спецификаторов доступа (служебных слов) - private (собственный), protected (защищенный), public (общедоступный), но и выбор ключевого слова class, struct, union, с помощью которого объявлен класс.

    На следующем шаге мы рассматрим определение производного класса.




Предыдущий шаг Содержание Следующий шаг