Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Вопросы по Embarcadero RAD Studio XE4

Модерирует : ShIvADeSt

 Версия для печати • ПодписатьсяДобавить в закладки
Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39

Открыть новую тему     Написать ответ в эту тему

Eternal_Shield

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
ego666
Не успел, deks уже привёл тот участок кода.

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

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

Код:
 
var
  List: IList;
...
List := IFileList(TFileList.Create);
 

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

Всего записей: 766 | Зарегистр. 18-05-2009 | Отправлено: 12:05 19-06-2013 | Исправлено: Eternal_Shield, 12:06 19-06-2013
deks



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
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) не хотим!

Всего записей: 857 | Зарегистр. 09-10-2003 | Отправлено: 12:06 19-06-2013
AlekXL



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Arioch1

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

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

Всего записей: 792 | Зарегистр. 24-04-2008 | Отправлено: 13:56 19-06-2013
Frodo_Torbins

Silver Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
AlekXL
Загляните под капот. Интерфейс это по сути запись с полями процедурного типа. Унаследованый интерфейс содержит теже поля что и родитель, плюс свои. Если класс поддерживает и родительский интерфейс и наследника, то у него в VMT две эти записи и в этих записях первые поля совпадают по сигнатурам и расположению, но могут иметь разные значения.

Всего записей: 2318 | Зарегистр. 24-05-2007 | Отправлено: 17:43 19-06-2013
deks



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
AlekXL
Frodo_Torbins
 
А в Оксигене у интерфейса могут быть property и event ...  _http://wiki.oxygenelanguage.com/en/Interface_(keyword) )))
 
А про VMT/переменные - дык как я понимаю, вы об одном и том же говорите! Наследование = 2 записи в VMT. Полиморфизм = разные указатели на реализующие функции.
 
Но если мы спускаемся до деталей реализации подкапотного хозяйства, то лучше вернуться на уровень выше: в языке есть фича, и она должна как-то вменяемо работать! А у Дельфи есть свойство косячить с некоторыми фичами.. Вот своеобразное поведение с "доставанием" родительского интерфейса. Кто то record helper вспоминал раньше. Были еще темы с дженериками (их вспоминать вообще не хочется!)
 

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

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

Всего записей: 857 | Зарегистр. 09-10-2003 | Отправлено: 18:06 19-06-2013
delover

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
deks

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

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

Код:
QueryProc.Lock;
if  
     Assigned(QueryProc)  
   then  
     QueryProc(IID, Obj);  
QueryProc.Unlock;
(*
  Почему нет файнали? - Пусть ей повезёт и сдохнет раньше. Но в зависимости от реализации файнали только приветствуется.
*)

Я не меняю QueryProc как перчатки в зависимости, что не успел проанализировать стэк. Я отмечу - процессор может не соблюдать идентичность кэша проца и памяти в зависимости от галочек ускорения и девелопер может быть в заблуждении. (попытался озвучить).
 
Теперь мой пример. Я в детстве умел только реализовывать интерфейс Cildren. Потом оказалось что Parent. А про то что я приёмный я бы не хотел афишировать.
 
Добавлено:
deks

Цитата:
А у Дельфи есть свойство косячить с некоторыми фичами..

Ну Вы опережаете на 100 шагов. Я совершенно забыл слово агрегация. Возможна неправильная трактовка. Если реализуется именно агрегация, то нельзя быть неведомой зверушкой и равнять родителей под детей. Агрегация - договорённость о внешнем взаимодействии, тут нельзя использовать политику IUnknown. То что впитываем - впитываем без остатка.

Всего записей: 1395 | Зарегистр. 25-06-2007 | Отправлено: 19:18 19-06-2013
reenoip



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Благодаря вашей беседе я лишь лишний раз убедился, что я не программист.
Это радует и настораживает одновременно

Всего записей: 1768 | Зарегистр. 10-03-2006 | Отправлено: 19:46 19-06-2013
deks



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
delover
 
Многа букафф - ниасилил! Не понял к чему именно этот пост. Попроще плиз

Всего записей: 857 | Зарегистр. 09-10-2003 | Отправлено: 20:12 19-06-2013
delover

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
deks

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

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

Всего записей: 1395 | Зарегистр. 25-06-2007 | Отправлено: 21:04 19-06-2013
ego666

Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

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

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

Код:
List := IFileList(TFileList.Create);

Это неверная запись для получения интерфейса из объекта. При неявном касте используется статическая проверка, а т.к. IFileList является наследником IList, то компилятор считает данное выражение верным (а то что это работает и указатель на vmt корректно определился - просто совпадение). Оно и верно - работает полиморфизм, только применять его нужно там, где он именно нужен (для чего он предназначен).
 
Добавлено:
А вот для получения интерфейса из объекта действуют другие правила, полиморфизм к ним не применим (он и не нужен и не предназначен для этого).

Код:
List := TFileList.Create as IFileList;

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

Цитата:
Если схема работы IFileList не совместима с использованием IList - то зачем декларировать наследование интерфейса?

Я так захотел. Я так могу. Это правильно.
Потому что я хочу унаследовать все методы IList, унаследовать так сказать "контракт" на поддержку этих методов в дальнейшем, в наследниках и классах их реализующих. Зачем мне заниматься копи-пастом, вводя новый интерфейс с точно такими же методами? Почему я не могу просто их унаследовать? Это же повторное использование, чёрт возьми!
 
Добавлено:

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

Не всегда, а в конкретной исключительной ситуации. В обычной ситуации мы пишем базовый интерфейс, пишем реализующий его класс, потом пишем наследника интерфейса, наследуемся от предыдущего класса и реализовываем в нём новый интерфейс и т.д. и т.п. и в таком случае любой наследник класса будет поддерживать любой родительский интерфейс (читай без нужды явного его указания в классе).
 
Добавлено:
А вообще, возможность явно указывать или не указывать поддержку интерфейса - даёт разработчику большие возможности (выше уже кто-то приводил пример с поддержкой 100500 интерфейсов, без явного указания в классе, путём переопределения QueryInterface).
 
Добавлено:

Цитата:
Ну вот уже интереснее. Тогда встречный вопрос - а зачем ВООБЩЕ нужно наследование в интерфейсах?

Выше уже писал - полиморфизм, но к получению интерфейса из объекта - это не относится.
 
Добавлено:

Цитата:
Мы кагбэ не про COM говорим, а про интерфейсы Дельфи.

Когда я говорю о COM - я говорю конкретно об его архитектуре интерфейсов, которые в принципе не завися от платформы, где они могут быть реализованы (будь то Delphi или Windows).
 
Добавлено:

Цитата:
А в Оксигене у интерфейса могут быть property и event

в интерфейсах Delphi тоже могут быть проперти, если что.

Всего записей: 77 | Зарегистр. 14-06-2013 | Отправлено: 09:35 20-06-2013 | Исправлено: ego666, 09:35 20-06-2013
Eternal_Shield

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
ego666
Целью моего поста было обратить внимание на то, что явное указание разрешает проблему. Не важно каким образом происходит явное указание (хардкаст или софткаст).  
 

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

Я в курсе, какая разница между кастами, спасибо за заботу.

Всего записей: 766 | Зарегистр. 18-05-2009 | Отправлено: 10:24 20-06-2013
ego666

Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Вообще, в оксигене я люто завидую только одной штуке:
http://wiki.oxygenelanguage.com/en/Class_Contracts
 
Добавлено:

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

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

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

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

Код:
Pointer(Parent) := Pointer(TFooBar.Create);

или сразу таким

Код:
Pointer(Parent) := Pointer($987654);

если тебе бесконечно везёт.
 
Добавлено:
P.S.
если что, правильное решение юзать
Код:
as

Всего записей: 77 | Зарегистр. 14-06-2013 | Отправлено: 10:24 20-06-2013
deks



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
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;
 

 
Скомпилируй его и расскажи мне о результатах! )
Мне особенно интересна правильная строчка "iList := TFileList.Create as IFileList;"
 
П.С. В "неправильном Оксигене", чьи ущербные интерфейсы не освящены удивительно мудрыми проектировщиками COM, этот код компилируется, ага))

Всего записей: 857 | Зарегистр. 09-10-2003 | Отправлено: 11:36 20-06-2013 | Исправлено: deks, 15:17 20-06-2013
neznayka3

Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
del

Всего записей: 385 | Зарегистр. 07-06-2007 | Отправлено: 13:30 20-06-2013 | Исправлено: neznayka3, 13:31 20-06-2013
delover

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
deks
Немного не так. (У меня уже в привычку).

Код:
type
//not foo not number
IChild=interface;
ISchool=interface(IChild);
IInstitute=interface(ISchool);
IWedding=interface(IInstitute);
IParent=(IWdding);

Есть цикл куда пускают только Support(IChild). Там надо следить когда чилды по лестнице лазиют. Ко мне пришлёпал один парент - ну полазай. Так с него за двоих брать или за одного?  

Всего записей: 1395 | Зарегистр. 25-06-2007 | Отправлено: 19:48 20-06-2013 | Исправлено: delover, 07:37 22-06-2013
ego666

Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

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

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

Код:
   IFileList = interface
   ['{466F0E31-B670-4DA2-8C2D-6342CF7AD1FB}']
     function Id: String;
   end;

Компилируется.
 
delover
завязывай курить
 
Добавлено:
Интересно, а такое оксиген могёт?

Код:
var
  Obj: TObject;
  IId: TGUID;
  List: IFileList;
begin
  Obj := TFileList.Create;
  IId := IFileList;
 
  //из заранее неизвестного объекта - получаем заранее неизвестный интерфейс
  Obj.GetInterface(IId, List);
 
  Writeln(List.Id);
end.

Фабрики не предлагать.

Всего записей: 77 | Зарегистр. 14-06-2013 | Отправлено: 05:28 21-06-2013 | Исправлено: ego666, 05:58 21-06-2013
delover

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

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


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

Код:
 
var
  v1, v2: variant;
begin
  v1 := 1;
  v2 := ' list';
  showmessage(concat('text: ', string(v1), v2)); // проходит
  showmessage(concat('text: ', v1, v2)); // ошибка

Я подумал, что если напишу concat, то будет неявное преобразование в строку...

Всего записей: 1395 | Зарегистр. 25-06-2007 | Отправлено: 07:58 21-06-2013
deks



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
ego666
 
С Гуидом не спортивно - это ж вроде как опциональный элемент!) Я то и прикалывался, что  
у Дельфи работа языковой конструкции "as" завязана на опциональный атрибут. Это не есть очень хорошо, потому как непонятно - нафига нужно название интерфейса тогда. Я понимаю что в COM интерфейсы маркируются GUIDами, но это какая-то лишняя привязка.
 
А оксиген может довольно хитро получать интерфейсы из всяких разных объектов, ага. Вот тут почитайте про "утиную типизацию": http://wiki.oxygenelanguage.com/en/Duck_Typing
 
Удобная штука, кстати.

Всего записей: 857 | Зарегистр. 09-10-2003 | Отправлено: 08:58 21-06-2013
valgreesh



Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
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 и умению дельфей конструировать виртуальные интерфейсы в рантайме.

Всего записей: 290 | Зарегистр. 30-11-2011 | Отправлено: 10:10 21-06-2013 | Исправлено: valgreesh, 10:14 21-06-2013
deks



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
valgreesh
 
Спасибо что объяснил, но я ничего не спрашивал)) Я и так знаю, что интерфейсы дельфи жестко завязаны на архитектуру COM, и что в этом их "особенность". Особенно трогательно она смотрится на iOS, на котором COM нету!) Ну и на андроиде - будет самое к месту))
 
А если серьезно, то в свое время в Дельфи стоило ввести нормальный "внутренний" для Дельфи интерфейс, а для COM делать надстройку над этим механизмом. А то песочница-песочницей, а внутри песочницы чего-то некрасиво) Ну или такой штукой стоит озаботится прямо сейчас, в NextGen компиляторе.  
 
И да, текущий компилятор Дельфи мог бы ругнуться на отсутствие GUID у интерфейса, если этот интерфейс используется в "as". Я уж не говорю про "сгенерировать" гуид "под капотом", чтобы не грузить пользователя деталями реализации (к 18-й версии компилятора то!).
 
Добавлено:

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

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

Всего записей: 857 | Зарегистр. 09-10-2003 | Отправлено: 10:22 21-06-2013 | Исправлено: deks, 10:59 21-06-2013
Открыть новую тему     Написать ответ в эту тему

Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39

Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Вопросы по Embarcadero RAD Studio XE4


Реклама на форуме Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.B0ard
© Ru.B0ard 2000-2024

BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

Рейтинг.ru