Дублируемое наследование (repeated inheritance) возникает, когда класс является потомком другого класса более чем на одном пути наследования. При этом возникает потенциальная неоднозначность, которую и следует разрешить.

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

Общие предки

Множественное наследование не запрещает, например, того, чтобы класс D был наследником классов B и C, каждый из которых является потомком класса A. Эту ситуацию и называют дублируемым наследованием.

Рис. 15.15.  Дублируемое наследование

Если B и C наследники потомков A, (случай 1), то такое наследование именуется косвенным. Если A, B и C - это один класс (случай 2), - наследование именуется прямым, что может быть записано в виде:

class D inherit

A

A

...

feature

...

end

По обе стороны океана

Следующий пример позволит нам промоделировать ситуацию дублируемого наследования и изучить возникающие проблемы. Пусть класс DRIVER имеет атрибуты:

age: INTEGER

address: STRING

violation_count: INTEGER -- Число записанных нарушений

и методы:

pass_birthday is do age := age + 1 end

pay_fee is

-- Оплата ежегодной лицензии.

do ... end

Класс наследник, US_DRIVER учитывает налоговое законодательство США, другой, FRENCH_DRIVER, - налоговое законодательство Франции.

Рассмотрим категорию людей, которым в течение года приходится водить машину в обеих странах. Нужного класса у нас еще нет, и простым решением этой проблемы кажется множественное наследование. Опишем класс FRENCH_US_DRIVER как порожденный от US_DRIVER и FRENCH_DRIVER. Налицо дублируемое наследование.

Рис. 15.16.  Типы водителей

Совместное использование и репликация

Из приведенного примера вытекает основная проблема дублируемого наследования: каков смысл компонентов дублируемого потомка (FRENCH_US_DRIVER), полученных от дублируемого предка (DRIVER)?

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

Внимательно перечитайте правило о конфликте имен:

Класс, наследующий от разных родителей различные компоненты с идентичным именем, некорректен.

Компоненты age (также как и pass_birthday), наследованные классом FRENCH_US_DRIVER от обоих родителей, не являются 'различными', поэтому реального конфликта не возникает. Заметьте, неоднозначность могла бы возникнуть лишь в случае переопределения компонента в одном из классов. Чуть позже мы покажем, как справиться с этой проблемой, а пока предположим, что переопределений не происходит.

Если компонент дублируемого предка под одним и тем же именем наследуется от двух и более родителей, он становится одним компонентом дублируемого потомка. Этот случай будем называть совместным использованием компонента (sharing).

Всегда ли применяется совместное использование? Нет. Рассмотрим компоненты address, pay_fee, violation_count. Обращаясь в службу регистрации автотранспорта в разных странах, водители скорее всего будут указывать разные адреса и по-разному платить ежегодные сборы. Впрочем, и нарушения правил тоже будут различны. Каждый из таких компонентов, следует представить в дублируемом потомке двумя разными компонентами. Данный случай будем называть репликацией (replication).

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

Чтобы совместно использовать один из компонентов, достаточно под одним именем унаследовать исходную версию этого компонента от обоих родителей. Но как реализовать репликацию? Делая все

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату