В предыдущей лекции мы обсудили переопределение компонентов, полученных по наследству. (Помните, что переопределение эффективного компонента задает его новое определение, а для отложенного компонента задает его реализацию.) Сравнение переименования и переопределения компонентов поможет многое прояснить.
При помощи переопределения можно добиться того, чтобы одно и то же имя компонента ссылалось на фактически различные компоненты в зависимости от типа объекта, к которому оно применяется (в этом случае говорят о динамическом типе соответствующей сущности). Это - семантический механизм.
Смена имен - это синтаксический механизм, позволяющий ссылаться на один и тот же компонент, фигурирующий в разных классах под разными именами.
Иногда то и другое можно совмещать:
class SANTA_BARBARA inherit LONDON rename foo as fog redefine fog end ...
Если, как и раньше, l: LONDON; s: SANTA_BARBARA, и выполнено присваивание l := s, то оба вызова l.foo, s.fog включают переопределенную версию компонента fog, объявление которого должно появиться в предложении feature класса.
Заметьте: redefine содержит уже новое имя компонента. Это нормально, поскольку под этим именем компонент известен классу. Именно поэтому rename должно находиться выше всех остальных предложений наследования (таких, как redefine и пока неизвестные читателю export, undefine, select). После выполнения rename компонент теряет свой прежний идентификатор и становится известным под новым именем классу, его потомкам и его клиентам.