Основы объектно-ориентированного программирования

         

Переименование


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

  • требовать от клиентов устранения всех неоднозначностей;
  • выбирать некую интерпретацию по умолчанию.

В соответствии с первым подходом, класс C, наследующий компонент f от A и B, будет нормально откомпилирован, возможно, с выдачей предупреждения. Ничего страшного не произойдет, пока в тексте клиента C не обнаружится нечто подобное:

x: C ... x.f ...

Клиенту придется квалифицировать ссылку на f, используя нотацию, например, такую: x.f | A, либо x.f | B, чтобы указать подразумеваемый класс.

Это решение противоречит, однако, одному из принципов, важность которого мы подчеркивали в этой лекции: структура наследования класса касается лишь самого класса и его предков, но не клиентов, за исключением случаев полиморфного применения компонентов. Пользуясь f из C, я не должен знать о том, введена эта функция классом C либо получена им от A или B.

Согласно второй стратегии, запись x.f корректна. Выбор одного из вариантов делается средствами языка. Критерием выбора является, например, порядок, в котором C перечисляет своих родителей. Для обращения к другим вариантам может существовать особая форма записи.

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

Эти проблемы решает смена имен. Одним из ее преимуществ является возможность создания клиентского интерфейса с "понятными" именами компонентов.



Содержание раздела