Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.03.14;
Скачать: CL | DM;

Вниз

Привести 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;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.025 c
1-43584
Kraft
2004-02-25 14:49
2004.03.14
Как запретить горячие клавиши


14-43853
Александр Иванов
2004-02-21 11:22
2004.03.14
Стоимость разработки


14-43816
Nick_Omsk
2004-02-23 00:21
2004.03.14
Соединение на прямую


1-43472
Mentov
2004-02-26 18:14
2004.03.14
Документация по RichEdit


3-43260
MadGhost
2004-02-13 08:29
2004.03.14
DBGrid как узнать выделена ли строка?