Ru-Board.club
← Вернуться в раздел «Прикладное программирование»

» Вопросы по Embarcadero RAD Studio XE4

Автор: deks
Дата сообщения: 18.06.2013 19:37
Arioch1

Цитата:
или мы не сможем достать родительский интерфейс из объекта!  

Ибо его там нет.


Да вот фиг то там! Он есть - попробуйте объявить класс с поддержкой IChild и не объявить все реализации методов для IParent! Вот именно это обстоятельство мне и кажется нелогичным: компилятор при декларации требует методы родительского интерфейса реализовать, а вот каст не проходит. Да, ромбовидное наследование.. Но вот когда его нету - в чем проблема? У Оксигена такой проблемы нету.


Цитата:
главный глюу с интерфейсами был в GUID


Согласен. Я просто считаю, что главная ошибка была в смешивании понятий интерфейс и MS COM. На определенный период COM было круто (да и сейчас возможность рулить ms word/excel это сильно), но "фундаментальную" языковую фичу так жестко привязывать к win платформе - не айс. Лучше бы сделали "диалект" интерфейсов, заточенный строго под COM: со своим наследованием, и прочими прибамбасами платформы!

Ну а про наследование интерфейсов - хз. Вроде бы практически удобная фича для всяких извратов архитектуры. Излишество? В какой то мере.. Но строго говоря все, что выше в абстракции чем asm - уже излишество той или иной степени!
Автор: Arioch1
Дата сообщения: 18.06.2013 19:45
Переменные IParent копируются в IChild, и этим переменным нужно назначить значение - ссылку на реализующий метод. Но это не значит, что присутствует сам IParent.


Цитата:
ошибка должна быть о нехватке IChild.P1


Просто добавь к ним всем GUIDы и подумай как в одном и том же поле IChild хранить сразу 2 (3? 4? ...) GUIDa для себя и для родителя.

Добавлено:
наследовать - по смыслу, вкладываемому в слово - можно поведение, т.е. реализацию, т.е. классы.
наследовать переменные - интерфейсы, record'ы - это оксюморон. Сами себя запутываем.


Цитата:
Вроде бы практически удобная фича для всяких извратов архитектуры


Это mix-ins из Питона и traits из Скалы, возможно и частичные классы.
Вроде бы это золотая середина позволяющая частично наследовать реализацию из нескольких классов и не уткнуться в ромб. Полу-множественное наследование.

Но ее в Delphi нет.
Автор: deks
Дата сообщения: 18.06.2013 20:30
Arioch1

Ну - чего и куда копируется это детали реализации. Главное, что класс TChild реализовал и IChild, и, соответственно IParent. Поэтому было бы логичным дать возможность достать из TChild искомый IParent напрямую!

И, кстати, не совсем понял зачем в одном и том же поле хранить 2-3 значения? Если про способ реализации интерфейсов - то смотрим в сторону C++, там все давно расписано и с деталями реализации. Любое извращение найти можно))

Про наследование. Ну - не совсем согласен что для интерфейсов это оксюморон. Если относиться к интерфейсу как к протоколу, то по мне так логично будет расширять протокол дочерним протоколом, добавляющим какую-то специфику или новый слой функционала (HTTP -> WebDAV).
Автор: delover
Дата сообщения: 18.06.2013 20:40

Цитата:
Да вот фиг то там! Он есть - попробуйте объявить класс с поддержкой IChild и не объявить все реализации методов для IParent!

Немного не так. QueryInterface виртуальный метод. Я ничего вообще не объявлял, есть динамический TInterfaceList который я поддерживаю, то есть отдаю когда вы пишете as IIntf. В классе реализующем список восьмидесяти интерфейсов нет ни одного метода этих интерфейсов. Я их добавляю - удаляю из списка по усмотрению.

Код:
function TClassFoo.QueryInterface(const IID: TGUID; out Obj): HResult;
begin
Result := inherited QueryInterface(IID, Obj);
if Result and $80000000 <> 0
then Exit;
if
Assigned(QueryProc)
then
QueryProc(IID, Obj);
end;
Автор: Arioch1
Дата сообщения: 18.06.2013 21:03

Цитата:
Главное, что класс TChild реализовал и IChild, и, соответственно IParent.


да нет же!


Код: a := b
Автор: deks
Дата сообщения: 18.06.2013 21:23
delover

Вы мне рассказываете о деталях реализации интерфейсов на Win32, сделанных для совместимости с COM. Вспомним что еще бы GUID неплохо интерфейсу присвоить!)

Arioch1

Цитата:
это не делает их одним интерфейсом


В коде прямо написано "IChild = interface(IParent)" - что должно прямо делать их родительским интерфейсом и дочерним. Дельфи выбрало путь сожительства интерфейсов с COM, а наследование интерфейсов так себе сочетается с COM. Отсюда и все обсуждаемые сложности)))

Я не против текущего решения с интерфейсами в Дельфи, я даже понимаю почему именно это так. Просто это такой не очень логичный и местами не очень удобный динозавр)) Жить с этим можно!

Ну и важно - в этом случае "особенности" интерфейсов дельфи имеют довольно понятные причины. В отличие от особенностей реализации TList<>
Автор: ego666
Дата сообщения: 19.06.2013 06:24

Цитата:
Не IDispatch ли решает подобную проблему .. по типу той, что в примере? ...

Неее, ну его нафиг делать это через IDispatch.


Цитата:
и как сие попадает под определение, что родитель должен знать о всех методах всех своих наследников?

Эмм.. да я такого и не говорил и даже такого нигде не подразумевал.


Цитата:
В нашем случае, как IList может знать о методах в своих наследниках IFileFile, IStreamList и т.п.? С какого перепугу vtbl родителя изменится, чтобы отразить методы его наследников? ...  

Ты меня наверное не понял, покажи в моём коде что ты имеешь ввиду? (и я тебе покажу, что я другое имею ввиду)

Добавлено:

Цитата:
Хм. Тогда переспрошу - а чем принципиально отличаются интерфейсы C#/Java от Delphi?

http://docwiki.embarcadero.com/RADStudio/XE2/en/Object_Interfaces_Index


Цитата:
Пока мне кажется, что в Дельфи использование наследования интерфейсов происходит через Ж. Абсолютно не вижу логики.  

Чукча не читатель?
http://forum.ru-board.com/topic.cgi?forum=33&topic=13680&start=357&limit=1&m=1#1
http://forum.ru-board.com/topic.cgi?forum=33&topic=13680&start=374&limit=1&m=1#1

Добавлено:

Цитата:
WTF! - нелогично же. Зачем так сделано? Понимаю все проблемы COM, но это ж прошлый век! Даже голимый C# от этого ушел!

Интерфейсы в COM спроектировали очень грамотно, вдумываясь учли все возможные нюансы.
А вот в Шарпе (и подобных) их тупо, не думая, слепили из абстрактных классов.

Добавлено:

Цитата:
По поводу примера с IList и IFileList. А с какого перепуга мы достаем из объекта интерфейс IList и пытаемся работать с ним как с IFileList?

Покажи кодом, где я достаю IList и работаю с ним как с IFileList?


Цитата:
Когда же предок позволял работать с собой как с потомком?

Где это в моём коде?

Ещё раз вдумчиво посмотри пример (ссылка выше).

Добавлено:

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

Ситуации бывают разные.

Добавлено:

Цитата:
  THermAphrodite=class(TInterfacedObject,IBoy,IGirl)
  public
    function PreferDolls_Yes: Boolean; // for girls
    function PreferDolls_No: Boolean; // for boys

    function IGirl.PreferDolls = PreferDolls_Yes;
    function IBoy.PreferDolls = PreferDolls_No;  
end;

Скрестил ужа с ежом. И что по твоему должен вернуть метод PreferDolls, если бы ты кастанул объект к IParent?

Добавлено:
правильный ответ:
из объекта вообще нельзя получать интерфейс IParent, если только мы его явно не указали и не реализовали в классе объекта, ключевое слово явно, т.к. конкретно в этой ситуации, с IBoy и IGirl, IParent ну не нужно и нельзя получать из объекта, реализующего оба этих наследника.

Добавлено:

Цитата:
Да вот фиг то там! Он есть - попробуйте объявить класс с поддержкой IChild и не объявить все реализации методов для IParent! Вот именно это обстоятельство мне и кажется нелогичным: компилятор при декларации требует методы родительского интерфейса реализовать, а вот каст не проходит.

Потому что в интерфейсах наследуется интерфейс, не реализация как в наследовании классов, а интерфейс, который можно реализовать как угодно, не оглядываясь на родителя. Для IGirl реализовывает все методы IParent по своему, для IBoy - по своему.

Добавлено:

Цитата:
Я просто считаю, что главная ошибка была в смешивании понятий интерфейс и MS COM.

Ты можешь как угодно считать? В то время, по крайней мере, Delphi разрабатывали не дураки. Если именно так сделали, значит именно так и нужно было делать.

Добавлено:
Ты можешь как угодно считать. (тут без знака вопроса, боюсь править пост - опять свернётся)

Добавлено:

Цитата:
В коде прямо написано "IChild = interface(IParent)" - что должно прямо делать их родительским интерфейсом и дочерним.

для классов свои правила, для интерфейсов - свои, не надо их равнять между собой, правила классов неприменимы к интерфейсам, потому что там наследуются реализации и наследник класса обязан "поддерживать" родителя, а интерфейсов фактически ничего не наследуется и его ничто не обязывает "поддерживать" родителя.
Автор: deks
Дата сообщения: 19.06.2013 08:19
ego666


Цитата:
Покажи кодом, где я достаю IList и работаю с ним как с IFileList?


var List: IList;
..

List := TFileList.Create; // достаем IList из TFileList
..
А вот тут пытаемся работать с IList с помощью методов определенных для IFileList:
List.Open(...) //<- ошибка, в IList нет метода Open



Добавлено:

Цитата:
интерфейс, который можно реализовать как угодно, не оглядываясь на родителя


Я же говорю не со стороны реализации, а со стороны использования! Если дочерний интерфейс реализует все методы родительского - то в чем проблема кастануть его к родительскому? Одну проблему уже указали - diamond problem. Имхо, она легко решается уточнением.


Цитата:
В то время


Времена меняются))


Цитата:
наследник класса обязан "поддерживать" родителя


No. Все ровно наоборот: наследник класса вообще не обязан ничего с родителем делать. "TChild = class(TParent) end; " - это полностью готовый к использованию валидный класс, который включает в себя и декларацию, и реализацию. Обращаем внимание - наследник ничего не делает для поддержки родителя.

У интерфейсов декларация в одном месте, реализация в другом. Если с декларацией все абсолютно так же как и с классами, то с реализацией чуть сложнее. требуется полностью реализовать все методы: и ЯВНО поддерживаемого интерфейса, и РОДИТЕЛЬСКОГО интерфейса.

Однако речь шла не о реализации, а ОБ ИСПОЛЬЗОВАНИИ интерфейсов. Вот тут мне до сих пор непонятен вопрос - почему есть проблемы с кастом до родительского интерфейса в очевидных случаях. У части "альтернативных паскалей" такой проблемы нету.


Цитата:
Хм. Тогда переспрошу - а чем принципиально отличаются интерфейсы C#/Java от Delphi?
http://docwiki.embarcadero.com/RADStudio/XE2/en/Object_Interfaces_Index
 


Чего уж - сразу на Гугл ссылку давать надо)) Но на самом деле - если по существу сказать нечего, лучше промолчать, за умного сканаешь!
Автор: X11
Дата сообщения: 19.06.2013 09:21
Информация по разработке для мобильных систем

The Delphi Language for Mobile Development - техническая статья Марко Канту - PDF
http://img.en25.com/Web/Embarcadero/%7B9993955a-d923-4d02-8f00-0ac860d08556%7D_delphilanguagemobiledevelopmentwhitepaper170413.pdf

Обучающие материалы по разработке для iOS
http://docwiki.embarcadero.com/RADStudio/XE4/en/IOS_Tutorials:_Delphi_iOS_Application_Development?elq=db7ea77a14064544978abeea8902e832&elqCampaignId=187
Автор: ego666
Дата сообщения: 19.06.2013 09:51

Цитата:
var List: IList;
..

List := TFileList.Create; // достаем IList из TFileList
..
А вот тут пытаемся работать с IList с помощью методов определенных для IFileList:
List.Open(...) //<- ошибка, в IList нет метода Open

Вот именно, что при текущем положении вещей, я не смогу достать IList из TFileList, а если бы мог - то не смог правильно с ним работать, ведь у него нет необходимых из IFileList, которые нужно обязательно вызывать.


Цитата:
Одну проблему уже указали - diamond problem. Имхо, она легко решается уточнением.  

Проблему ромба ты не решил. Другая проблема - ох... эта та о которой я уже талдычу последние N страниц.

Добавлено:

Цитата:
No. Все ровно наоборот: наследник класса вообще не обязан ничего с родителем делать. "TChild = class(TParent) end; " - это полностью готовый к использованию валидный класс, который включает в себя и декларацию, и реализацию. Обращаем внимание - наследник ничего не делает для поддержки родителя.

Лукавишь. Принцип подстановки Лисков.

Добавлено:
А именно:

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


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

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

Добавлено:

Цитата:
У части "альтернативных паскалей" такой проблемы нету

Потому что они просто не задумывались, в отличии от проектировщиков COM.
Автор: Eternal_Shield
Дата сообщения: 19.06.2013 11:05
ego666
Не успел, deks уже привёл тот участок кода.

Цитата:
Вот именно, что при текущем положении вещей, я не смогу достать IList из TFileList, а если бы мог - то не смог правильно с ним работать, ведь у него нет необходимых из IFileList, которые нужно обязательно вызывать.

Кстати, это похоже на баг компилятора, ибо если чётко указать, какой интерфейс-наследник объект реализует, а-ля:

Код:
var
List: IList;
...
List := IFileList(TFileList.Create);
Автор: deks
Дата сообщения: 19.06.2013 11:06
ego666

Цитата:
ведь у него нет необходимых из IFileList, которые нужно обязательно вызывать


О, батенька! Так у нас проблемы с проектированием или интерфейсов или реализации! Нафига вы раньше в коде сказали - "IFileList = interface(IList)"? Если схема работы IFileList не совместима с использованием IList - то зачем декларировать наследование интерфейса? Вы же все равно не сможете его использовать в коде, который знает только про IList?!

А если по вашему наследование интерфейса - это когда каждый потомок полностью переопределяет всю логику работы базового интерфейса, то нафига такое наследование вообще нужно? Хотя многие web-сервисы таки работают с вашим подходом, возьмем например реализацию OAuth))


Цитата:
Проблему ромба ты не решил


Я сказал про типовой путь ее решения - уточнять неоднозначность по необходимости. Компилятор с этим вполне может справиться! Именно так делается для уже обсуждавшихся "примесей" во всяких явах. Конечно, есть и другая куча способов решения этой проблемы - смотрим C++, Pyton, Scala, Eiffel, etc.

Я к тому, что наличие этой проблемы не говорит о невозможности ее решения ни разу.


Цитата:
Лукавишь. Принцип подстановки Лисков.


Не лукавлю - 42! )) А если серьезнее, то: нафига давать ссылку на смутно относящуюся к теме статью. Своими словами нужно говорить, а не "ссылками на авторитеты".


Цитата:
Это не относится к интерфейсам, т.к. у них нет наследования реализации и не нужно к ним применять эти правила


Ну вот уже интереснее. Тогда встречный вопрос - а зачем ВООБЩЕ нужно наследование в интерфейсах? Чем наследование отличается от копипасты родиетльского интерфейса в потомка? То есть - какой по твоему мнению _практический_ смысл в наследовании интерфейсов? Если IChild унаследован от IParent, то что это должно означать при реализации IChild, и особенно при реализации неявно поддержанного IParent?


Цитата:
в отличии от проектировщиков COM


Мы кагбэ не про COM говорим, а про интерфейсы Дельфи. Не нужно смешивать мух и котлеты. COM немного не для обсуждаемых задач был сделан, он кагбэ interop на win-платформе обеспечивает. А мы говорим о том, чего Дельфи в интерфейсах не допускает и допускает. Интерфейсы Дельфи все же больше чем COM (например, вполне себе работают интерфейсы без GUID), и для языка они решают немного другие задачи.

Добавлено:
Eternal_Shield

Цитата:
это похоже на баг компилятора


Exactly! Мы один неявный каст делаем ( из TFileList в IFileList ), а двойной каст (сначала в IFileList, потом в IList) не хотим!
Автор: AlekXL
Дата сообщения: 19.06.2013 12:56
Arioch1

Цитата:
если в IChild входят несколько переменных, таких же как в IParent - это не делает их одним интерфейсом.

переменные ... в интерфейсе? Если IChild унаследован от IParent, то IChild является IParent. Принцип полиморфизма. Интерфейсы разные, но связаны наследованием.

--
не думал я, что этот мой вопрос столько баталий вызовет..
Автор: Frodo_Torbins
Дата сообщения: 19.06.2013 16:43
AlekXL
Загляните под капот. Интерфейс это по сути запись с полями процедурного типа. Унаследованый интерфейс содержит теже поля что и родитель, плюс свои. Если класс поддерживает и родительский интерфейс и наследника, то у него в VMT две эти записи и в этих записях первые поля совпадают по сигнатурам и расположению, но могут иметь разные значения.
Автор: deks
Дата сообщения: 19.06.2013 17:06
AlekXL
Frodo_Torbins

А в Оксигене у интерфейса могут быть property и event ... _http://wiki.oxygenelanguage.com/en/Interface_(keyword) )))

А про VMT/переменные - дык как я понимаю, вы об одном и том же говорите! Наследование = 2 записи в VMT. Полиморфизм = разные указатели на реализующие функции.

Но если мы спускаемся до деталей реализации подкапотного хозяйства, то лучше вернуться на уровень выше: в языке есть фича, и она должна как-то вменяемо работать! А у Дельфи есть свойство косячить с некоторыми фичами.. Вот своеобразное поведение с "доставанием" родительского интерфейса. Кто то record helper вспоминал раньше. Были еще темы с дженериками (их вспоминать вообще не хочется!)


Цитата:
не думал я, что этот мой вопрос столько баталий вызовет..


Лишний раз побеседовать о концептуальных вещах - полезно! Позволяет вспомнить о базовых штуках всяких)) Вот и про "ромбики" с наследованием даже вспомнили))
Автор: delover
Дата сообщения: 19.06.2013 18:18
deks

Цитата:
Просто это такой не очень логичный и местами не очень удобный динозавр)) Жить с этим можно!

Опять не совсем так. Мой пример ламерский для официальной публикации, я даже пишу Foo. На компьютере разработчика всё ОК, но на деле не так. Есть Биос который просил процессор работать в ускоренном режиме. Мой код при случае может дать нецелосность сисемы. Почему я выбрал QueryProc1????? Потому что при компиляции проекта я сказал QueryProc1 так как делал дебажную версию и знаю - нет ниодного созданного объекта. Надо делать так (это тех регламент)

Код: QueryProc.Lock;
if
Assigned(QueryProc)
then
QueryProc(IID, Obj);
QueryProc.Unlock;
(*
Почему нет файнали? - Пусть ей повезёт и сдохнет раньше. Но в зависимости от реализации файнали только приветствуется.
*)
Автор: reenoip
Дата сообщения: 19.06.2013 18:46
Благодаря вашей беседе я лишь лишний раз убедился, что я не программист.
Это радует и настораживает одновременно
Автор: deks
Дата сообщения: 19.06.2013 19:12
delover

Многа букафф - ниасилил! Не понял к чему именно этот пост. Попроще плиз
Автор: delover
Дата сообщения: 19.06.2013 20:04
deks

Цитата:
Просто это такой не очень логичный и местами не очень удобный динозавр)) Жить с этим можно!

Думаю это не имело отношения к тому что я писал, в случае с приёмными очень удобен. Но в основном хотел напомнить что я сначала был ребёнком, а потом родителем. Теперь мне надо учитывать стереотипы разработчиков которые считают - если ты чилд то и парент.
Автор: ego666
Дата сообщения: 20.06.2013 08:35

Цитата:
Кстати, это похоже на баг компилятора, ибо если чётко указать, какой интерфейс-наследник объект реализует, а-ля ..то всё работает.

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

Код: List := IFileList(TFileList.Create);
Автор: Eternal_Shield
Дата сообщения: 20.06.2013 09:24
ego666
Целью моего поста было обратить внимание на то, что явное указание разрешает проблему. Не важно каким образом происходит явное указание (хардкаст или софткаст).


Цитата:
Такая запись верная, её и следует применять. При явном касте уже будет использоваться динамическая проверка, на предмет поддержки указанного типа интерфейса.

Я в курсе, какая разница между кастами, спасибо за заботу.
Автор: ego666
Дата сообщения: 20.06.2013 09:24
Вообще, в оксигене я люто завидую только одной штуке:
http://wiki.oxygenelanguage.com/en/Class_Contracts

Добавлено:

Цитата:
Целью моего поста было обратить внимание на то, что явное указание разрешает проблему.

Не решает. Ты ничего не понял.


Цитата:
Не важно каким образом происходит явное указание (хардкаст или софткаст).

Конечно! Можно и таким:

Код: Pointer(Parent) := Pointer(TFooBar.Create);
Автор: deks
Дата сообщения: 20.06.2013 10:36
ego666

Вот такой код:

Код:
type
IFileList = interface
function Id: String;
end;

TFileList = class(TInterfacedObject, IFileList)
function Id: String;
end;

function TFileList.Id: String;
begin
Result := 'TFileList.Id';
end;

var
iList: IFileList;
begin
iList := TFileList.Create as IFileList;
writeln(iList.Id);
end;
Автор: delover
Дата сообщения: 20.06.2013 18:48
deks
Немного не так. (У меня уже в привычку).

Код: type
//not foo not number
IChild=interface;
ISchool=interface(IChild);
IInstitute=interface(ISchool);
IWedding=interface(IInstitute);
IParent=(IWdding);
Автор: ego666
Дата сообщения: 21.06.2013 04:28

Цитата:
Скомпилируй его и расскажи мне о результатах! )

Ты забыл гуид:

Код: IFileList = interface
['{466F0E31-B670-4DA2-8C2D-6342CF7AD1FB}']
function Id: String;
end;
Автор: delover
Дата сообщения: 21.06.2013 06:58

Цитата:
завязывай курить



У меня странно компилируется

Код:
var
v1, v2: variant;
begin
v1 := 1;
v2 := ' list';
showmessage(concat('text: ', string(v1), v2)); // проходит
showmessage(concat('text: ', v1, v2)); // ошибка
Автор: deks
Дата сообщения: 21.06.2013 07:58
ego666

С Гуидом не спортивно - это ж вроде как опциональный элемент!) Я то и прикалывался, что
у Дельфи работа языковой конструкции "as" завязана на опциональный атрибут. Это не есть очень хорошо, потому как непонятно - нафига нужно название интерфейса тогда. Я понимаю что в COM интерфейсы маркируются GUIDами, но это какая-то лишняя привязка.

А оксиген может довольно хитро получать интерфейсы из всяких разных объектов, ага. Вот тут почитайте про "утиную типизацию": http://wiki.oxygenelanguage.com/en/Duck_Typing

Удобная штука, кстати.
Автор: valgreesh
Дата сообщения: 21.06.2013 09:10
deks

Цитата:
С Гуидом не спортивно - это ж вроде как опциональный элемент!

Для интерфейсов которые могут быть запрошены (Interface querying) это таки обязательный элемент.


Цитата:
Я то и прикалывался, что у Дельфи работа языковой конструкции "as" завязана на опциональный атрибут

Опять же учим матчасть:

Цитата:
Interface Querying

You can use the as operator to perform checked interface typecasts. This is known as interface querying, and it yields an interface-type expression from an object reference or from another interface reference, based on the actual (run-time) type of object. An interface query has the form:

object as interface

where object is an expression of an interface or variant type or denotes an instance of a class that implements an interface, and interface is any interface declared with a GUID.

An interface query returns nil if object is nil. Otherwise, it passes the GUID of the interface to the QueryInterface method in object, raising an exception unless QueryInterface returns zero. If QueryInterface returns zero (indicating that the object's class implements the interface), the interface query returns an interface reference to object.



Цитата:
Это не есть очень хорошо, потому как непонятно - нафига нужно название интерфейса тогда.

Потому что нативный мир сильно неоднороден. А дельфя обеспечивает взаимодействие не только внутри своей закрытой песочницы (как это делают жаба с дотнетом), но и с внешним миром тоже.


Цитата:
А оксиген может довольно хитро получать интерфейсы из всяких разных объектов, ага. Вот тут почитайте про "утиную типизацию": http://wiki.oxygenelanguage.com/en/Duck_Typing Удобная штука, кстати

Эту штуку можно повторить и в дельфях, благодаря наличию богатого RTTI и умению дельфей конструировать виртуальные интерфейсы в рантайме.
Автор: deks
Дата сообщения: 21.06.2013 09:22
valgreesh

Спасибо что объяснил, но я ничего не спрашивал)) Я и так знаю, что интерфейсы дельфи жестко завязаны на архитектуру COM, и что в этом их "особенность". Особенно трогательно она смотрится на iOS, на котором COM нету!) Ну и на андроиде - будет самое к месту))

А если серьезно, то в свое время в Дельфи стоило ввести нормальный "внутренний" для Дельфи интерфейс, а для COM делать надстройку над этим механизмом. А то песочница-песочницей, а внутри песочницы чего-то некрасиво) Ну или такой штукой стоит озаботится прямо сейчас, в NextGen компиляторе.

И да, текущий компилятор Дельфи мог бы ругнуться на отсутствие GUID у интерфейса, если этот интерфейс используется в "as". Я уж не говорю про "сгенерировать" гуид "под капотом", чтобы не грузить пользователя деталями реализации (к 18-й версии компилятора то!).

Добавлено:

Цитата:
Эту штуку можно повторить и в дельфях


Повторите - интересно!) А как?

Есть готовый интерфейс с парой методов (List.Count, List.GetItem). Есть класс, для которого поддержка этого интерфейса не заявлена, но по названию/сигнатуре методов он подходит под интерфейс (Folder). Как заюзать объект этого класса через этот интерфейс?

P.S. Интересно просто связь вопроса с "богатым RTTI".
Автор: valgreesh
Дата сообщения: 21.06.2013 10:20
deks

Цитата:
Особенно трогательно она смотрится на iOS, на котором COM нету!) Ну и на андроиде - будет самое к месту))

Динамически подгружать библиотеки на этих платформах можно? Следовательно и применение интерфейсов в экспорте будет уместно. Загрузило приложение плагин, который в функцию инициализации получает интерфейс IApplication, а возвращает IPlugin. А дальше от этого плагина прилага может запросить интересующие её интерфейсы, а плагин от интерфейса приложения.


Цитата:
А если серьезно, то в свое время в Дельфи стоило ввести нормальный "внутренний" для Дельфи интерфейс, а для COM делать надстройку над этим механизмом

То есть для собственного велосипеда изобрести свой механизм запроса интерфейсов, свой механизм управления временем жизни (если без него, то потом хрен объяснишь почему после запроса "внутреннего" интерфейса объект продолжает жить своей жизнью, а после запроса COM-интерфейса управление временем жизни изменяется), а потом еще прикостылить поддержку COM... Лишняя путаница и ничего более. Зачем???


Цитата:
Ну или такой штукой стоит озаботится прямо сейчас, в NextGen компиляторе

Ага, мало там сломать собираются, еще пусть и интерфейсы сломают... Вообще без юзеров останутся.


Цитата:
И да, текущий компилятор Дельфи мог бы ругнуться на отсутствие GUID у интерфейса, если этот интерфейс используется в "as". Я уж не говорю про "сгенерировать" гуид "под капотом", чтобы не грузить пользователя деталями реализации (к 18-й версии компилятора то!).

Мог бы. А еще лучше, если бы они кодогенерацию нормальную сделали, и компилятор не сыпал бы ICE'ами на дженериках.

Добавлено:
deks

Цитата:
Повторите - интересно

Мне без надобности, а для форума не интересно. Смотри на TVirtualInterface. Механизм довольно простой - с методов снимаются сигнатуры, по этим сигнатурам создается виртуальный интерфейс который вызове методов делегирует к целевому объекту. Кто-то, кажется, в буржунете эту штуку даже делал.

Страницы: 1234567891011121314151617181920212223242526

Предыдущая тема: cxDBPivotGrid выгрузка в excel


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.