Наследование интерфейсов

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Наследование интерфейсов

Сообщение and » 05.10.2011 21:48:29

Я чего-то не понимаю в работе с интерфейсами, или в FPC баг?
Код: Выделить всё
Program Project1;
{$mode objfpc}{$H+}
{$R *.res}
  Uses
    SysUtils;
  Const
    iid_Ancestor='{D9CB4FCD-A690-4A99-BD48-A1997AA970CF}';
    iid_Descendant='{621EAF8F-8E07-4BFD-A3F5-DBE359496A7E}';
  Type
{$INTERFACES COM}
    IAncestor=Interface
              [iid_Ancestor]
              End;
    IDescendant=Interface(IAncestor)
                [iid_Descendant]
                End;
    TImplementation=Class(TInterfacedObject,IDescendant)
                    End;
Begin
  WriteLn(Supports(TImplementation,iid_Descendant));
  WriteLn(Supports(TImplementation,iid_Ancestor))
End.
Вывод:
Код: Выделить всё
TRUE
FALSE
FPC 2.7.1 вчерашний.

Добавлено спустя 3 часа 11 минут 7 секунд:
Хмм... Проверил аналогичный код в Delphi. Поведение такое же: родительский интерфейс not supported. Выходит, баг в моём понимании интерфейсов, и тему можно крыть.
Под занавес ткните plz, где почитать здравое про подобные тонкости - в первую очередь, про наследование. Оно, как выясняется, несколько отличается от наследования у классов.
Аватара пользователя
and
постоялец
 
Сообщения: 124
Зарегистрирован: 16.09.2009 17:11:01
Откуда: г. Гомель, Беларусь

Re: Наследование интерфейсов

Сообщение alexrayne » 06.10.2011 10:24:15

Интерфейсы неимеют такой наследуемости как классы, т.е IDescendant не совместим с IAncestor.
в классе реализуемые интерфейсы задаются как перечень именно интерфейсов которые выставляет сам класс.
у Вас, класс выставил IDescendant как реализованый и именно к нему можно обратиться. IAncestor - не заявлен как реализованый классом, и к нему, соответственно, напрямую от класса обратиться нельзя. если IAncestor поддерживает методы получения себя самого, то можно получить IAncestor через какойто метод IDescendant (кажись Iuncknown имеет такие способности).
alexrayne
постоялец
 
Сообщения: 125
Зарегистрирован: 03.12.2008 16:56:26

Re: Наследование интерфейсов

Сообщение Иван Шихалев » 06.10.2011 17:37:35

alexrayne писал(а):IDescendant не совместим с IAncestor

Вот как раз на уровне языка он совместим, т.е. переменной типа IAncestor можно присвоить значение типа IDescendant.
А с реализацией — да, в таблицу интерфейсов класса попадает только непосредственно указанный. Можно просто добавить его в объявление:
Код: Выделить всё
    TImplementation=Class(TInterfacedObject,IAncestor,IDescendant)
                    End;

Хотя чаще удобно реализовать наследуемые интерфейсы в наследуемых классах...
Аватара пользователя
Иван Шихалев
энтузиаст
 
Сообщения: 1138
Зарегистрирован: 15.05.2006 11:26:13
Откуда: Екатеринбург

Re: Наследование интерфейсов

Сообщение and » 07.10.2011 05:52:08

Иван Шихалев писал(а):в таблицу интерфейсов класса попадает только непосредственно указанный. Можно просто добавить его в объявление
Да, это понятно, что можно вписАть его в шапку класса, и всё заработает. Тем более что класс в моём примере (есть цепочка наследования интерфейсов, но нет цепочки классов, реализатор только один) просто _не_может_ не реализовывать IAncestor: компилятор заругается. Отчасти поэтому для меня и стала сюрпризом необходимость прописывать IAncestor явно.
Аватара пользователя
and
постоялец
 
Сообщения: 124
Зарегистрирован: 16.09.2009 17:11:01
Откуда: г. Гомель, Беларусь

Re: Наследование интерфейсов

Сообщение alexrayne » 08.10.2011 01:08:11

Вот как раз на уровне языка он совместим, т.е. переменной типа IAncestor можно присвоить значение типа IDescendant.

Да, это дает некоторую иллюзию того что наследник и отец одной крови. Но когда дело доходит до реализации интерфейсов, особенно до получения интерфейса запросом к IUncknown, выясняется что можно реализовать их совершенно разными методами. тобиш родство по духу еще присутствует (состав интерфеса), а по плоти (интерфейс-потомок может иначе реализовываться чем отец) уже нет.
Особенно это забавляет когда глядиш как MSVCшные мастера создают интерфейсы к классам - там замечательно видна вся эта поднаготная.
Пока вы работаете в пределах паскаля, такие трюки вам попадаются редко, но как только вы пытаетесь работать с СОМ объектами написаными на MSVC то разницу между интерфейсами отцом и потомком надо всегда иметь в виду, и отождествлять их - ошибка.
alexrayne
постоялец
 
Сообщения: 125
Зарегистрирован: 03.12.2008 16:56:26


Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4

Рейтинг@Mail.ru
cron