Репликация множественного наследования в Eiffel

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

deferred class A
  feature 
    a  deferred end
  end

deferred class B
  inherit A
    rename a as b end
  end

deferred class C
  inherit A
    rename a as c end
end

class D
  inherit 
    B
    C
    select c end
feature
  b do print("b") end
  c do print("c") end
end

Если я присоединю экземпляр D к объекту ob_as_c типа C, то ob_as_c.c напечатает "c", как и ожидалось. Однако, если прикрепить экземпляр к объекту ob_as_b типа B, то ob_as_b.b напечатает также и "c".

Это намеренное поведение? Очевидно, я хотел бы, чтобы ob_as_b.b напечатало "b".


person beckni    schedule 10.09.2015    source источник


Ответы (2)


Просто описываю фактическое поведение в EiffelStudio, которое может отличаться от фактической спецификации ECMA.

Происходит то, что без select и b, и c соответствуют версии a. Компилятор будет жаловаться, что у вас есть 2 подпрограммы с разными именами, но одной и той же версией. Используя `select', вы исправляете ошибку и сообщаете компилятору, что для динамического связывания используется версия c, и это не зависит от типа цели, она основана на типе цель во время выполнения.

person Emmanuel Stapf    schedule 10.09.2015
comment
Спасибо за объяснение. К сожалению, это делает функции наследования Eiffel гораздо менее полезными для меня. - person beckni; 14.09.2015
comment
Относительно спецификации ECMA: разве в 8.16.11, Определение: версия с динамической привязкой не указано, что в моем примере ob_as_b.b следует печатать b, так как существует только путь соответствия от D к B, а функция b из D является унаследованной функцией b из B? Предложение select должно иметь значение только при наличии двух или более путей соответствия. - person beckni; 14.09.2015

(Косметика: написание "отложено". Иначе не скомпилируется!)

«выбрать» влияет только на семантику вызова, целью которого является объект, объявленный с повторяющимся типом предка, здесь A, поскольку в этом случае нам нужно устранение неоднозначности. Для сущностей типа B, C или D неоднозначности нет, поэтому действуют обычные правила полиморфизма и динамического связывания: для одного и того же целевого объекта не имеет значения, объявлена ​​ли сущность (имя в программе) типа B или С.

-- Бертран Мейер

person Bertrand Meyer    schedule 24.09.2015
comment
То, что вы описываете, - это поведение, которого я ожидал, и которое, я думаю, указано в 8.16.11 стандарта ECMA. Однако это не то, что происходит в EiffelStudio: в моем примере результат ob_as_b.b зависит от предложения select в D, хотя B не является повторяющимся предком D. (Кстати, я исправил досадную опечатку.) - person beckni; 25.09.2015