Форум: "Основная";
Текущий архив: 2004.03.14;
Скачать: [xml.tar.bz2];
ВнизПривести Inteface to Classes. Найти похожие ветки
← →
Ш-К (2004-03-02 13:21) [0]Не наоборот. Собственно, нужно создать хоть приблезительный механизм.
Делаю два интерфейса:
IFrameItem = interface;
IFrameList = interface(IInterface)
["{7DE1440F-4232-48BE-83A4-CB1259560BD8}"]
function GetItem: IFrameItem;
...
end;
IFrameItem = interface(IInterface)
["{17309E1B-BE7C-44FF-8053-ACC38F07D1A9}"]
...
end;
Делаю два класса, "наследуясь" от них:
TFrameItem = class(TObject, IFrameItem)
...
end
TFrameList = class(TObject, IFrameList)
function GetItem: IFrameItem;
...
end;
Реализую метод:
function TFrameList.GetItem: IFrameItem;
begin
...
end;
Мне нужно, чтобы эта функция возвращала как-нибудь TFrameItem, а не IFrameItem
С классом я бы делал: IFrameItem as TFrameItem.
А как с интерфейсами?
← →
Romkin (2004-03-02 13:28) [1]ЗАчем? Интерфейсы на то и интерфейсы, чтобы через них работать. Возвращай интерфейс, не нужен тебе класс
function TFrameList.GetItem: IFrameItem;
begin
Result := TFrameItem.Create;
end;
← →
Digitman (2004-03-02 13:38) [2]
> Ш-К
твоим интерфейсным объектом (ссылка на который возвращается как рез-т вызова Get_Item), возможно, будет пользоваться процесс приложения, созданного отнюдь не в Делфи, и посему ничего не знающего о каких-то там Делфи-классах (но зато прекрасно взаимодействующего с интерфейсами)
спрашивается, на кой ляд возвращать вместо интерфейса ссылку на Делфи-класс, если вызывающий код все равно им вряд ли сможет корректно воспользоваться ? Особенно если сервер, реализующий данный интерфейс, является внешним (а не in-proc) сервером ?
← →
Тимохов (2004-03-02 13:46) [3]Теперь о моем опыте.
Как писал Эрик Хармон, не мешайте интерфейсы и объекты.
Пользуйтесь чем-нибудь одним. По опыту знаю, что это так. Можно, конечно, мешать, но проблем будет море. Если в реализации интерфейсов хочется все-таки иметь объекты, значит есть ошибка проектирования. Надо подумать как обойтись только интерфейсами.
← →
Ш-К (2004-03-02 14:21) [4]Я, наверно, привел не совсем удачный пример кода, того что мне надо.
Сабж нужен исключительно для внутренностей разрабатываемых классов. "Внешние объекты" к классам обращаться не будут.
Согласен насчет интерфейсов и того, для чего они нужны.
Да, есть ошибка в проектировании.
Есть большой работающий код. К нему надо добавить много интерфейсов. Переписывать зоново всё не разманно, уж лучше оставить.
Нужен вариант, как это можно исправить не переписуя ВСЁ.
Есть базовый класс, некоторые его свойства/методы надо превратить в интерфейсы. И чтобы реализация этих методов затрагивала потомков класса (уже разработаных), как можно меньше.
Понятнее задачу объяснить не могу. Но я и не прошу готовых решений. А чисто соображения, даже абстрактные. И желательно без поворачиваний пальцем у виска. На самом деле все не так уж и уродливо.
← →
Тимохов (2004-03-02 14:29) [5]Объяснил понятно.
Одно уточнение: я так понимаю, что нужно сделать так, чтобы наружу выходили интерфейсы, а внутри объекта можно было работать с объектами? Так?.
← →
Serginio666 (2004-03-02 14:40) [6]Вообще при запросе интерфейса объекта тебе передается Self+ смещение поля со ссылкой на VMT интерфейса. Сами методы интерфейса являются заглушками и в них только переход с коорекцией Self-InterfaceOffset и jmp TYouClass.YouMetod.
← →
Ш-К (2004-03-02 14:40) [7]Так. Причём у меня есть закономерность в классах:
если TFrameList1 = class(TObject, IFrameList), то свойство у это класса, которое получилось от IFrameItem есть TFrameItem1.
TFrameList2 -> TFrameItem2
TFrameList3 -> TFrameItem3
TFrameList4 -> TFrameItem4...
Хочу показать, что интерфейсы не пересекаются.
Вложенность связей TFrameList1 -> TFrameItem1 -> TFrameSubItem1
на 3 уровня.
← →
Serginio666 (2004-03-02 14:47) [8]Посмотри
http://www.rsdn.ru/Forum/Message.aspx?mid=527260&only=1
← →
Тимохов (2004-03-02 14:51) [9]У меня реализована подобная структура на основе TAggregatedObject.
У меня так
Есть глаынй объект, у него есть поля. Внутри объекта работаю с полями как с объектами. При этом главный объект поддерживает интерфейс доступа к полям. В реализации интерфейсных методов просто присваиваю, типа такого
FUNCTION TMLObjectFilter.__GetFld(const aIndex: Integer): IMLFieldFilter;
BEGIN
Result := Flds[aIndex];
END;
где
FUNCTION TMLObjectFilter.fGetFld(const aIndex: Integer): TMLFieldFilter;
BEGIN
Result := fFlds[aIndex] // fFlds - TList;
END;
При этом элемента fFlds идут от TAggregatedObject с контроллером, указывающем не главный объект. В этом случае все корректно работает.
Доказательство.
Сначала рассмотрим случай, когда не наследуемся от TAggregatedObject. В этом случае в __GetFld происходит AddRef, а затем после использования интерфейса Release и объект удаляется.
В случае использования TAggregatedObject в указанном случае вызывается AddRef у контроллека, и затем же после использования интерфейса у него вызывается. И сам контроллер уже должен решать, что ему делать - удаляться (если refcount = 0) или нет.
Если, что не понятно (думаю, что так, т.к. писать подробно нет времени), то спрашивай.
← →
Тимохов (2004-03-02 14:53) [10]Прошу прощение за поспешность :))))
← →
Ш-К (2004-03-02 15:06) [11]Serginio666
Да причем сдесь устройства интерфейсов и моя проблема.
Тимохов ©
Теплее, но для моей задачи не подходит. Я как раз и хочу, чтоб меньше было писать и не усложнять промежуточными класами.
Ладно, всем спасибо. Буду переписывать каждый объект руками.
← →
Serginio666 (2004-03-02 15:13) [12]Ш-К (02.03.04 15:06) [11]
Если знаешь что за объект реализовал этот интерфейс, то легко можно выйти на сам объект. Либо через некие манипуляции через код метода интерфейса. Но разумеется это относится к не отмаршалленным интерфейсам.
← →
Тимохов (2004-03-02 15:21) [13]
> Ш-К (02.03.04 15:06) [11]
Да в общем то усложнения я не вижу. Сделайте все потомком TAggregatedObject (стандратный) и все будет ок.
← →
hexone (2004-03-02 16:00) [14]Можно. Не парься. Другое дело, что осторожно.
interface ICLASS
function classptr : integer;
end;
TCLASS.classptr
begin
result := integer(Self);
end;
----> TCLASS(classptr).
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2004.03.14;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.012 c