Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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
1-43431
Layner
2004-03-01 09:50
2004.03.14
Как редактировать строки в ListView?


7-43907
Пользователь
2003-12-23 19:08
2004.03.14
Как спрятать прогу от диспетчера задач ?


1-43440
003
2004-02-29 23:51
2004.03.14
Rich Text Format


7-43919
Savage2003
2003-12-22 15:21
2004.03.14
Сервисы


8-43702
Klon
2003-11-14 12:27
2004.03.14
Разбиение многоугольников





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский