Форум: "Потрепаться";
Текущий архив: 2003.08.07;
Скачать: [xml.tar.bz2];
ВнизОбъектно-ориентированная технология Найти похожие ветки
← →
Димыч (2003-07-16 23:34) [0]Как сделать так, чтобы у нескольких объектов разных классов были общие свойства? Причем, становились бы они общими динамически.
← →
Palladin (2003-07-16 23:48) [1]я конечно не до конца понял что ты спросил, но могу предположить что речь идет о наследовании...
в таком случае придется тебе создать класс предок с этими общими свойствами и остальные классы наследовать от него...
type
TCommonClass=class
public
property Cmn1:integer ...
property Cmn2:string...
end;
TClass1=class(TCommonClass)
....
end;
и тд
← →
Chlavik (2003-07-17 03:21) [2]Может ты хочеш спросить про virtul или dynamic обявления методов?
← →
Думкин (2003-07-17 05:53) [3]По телепатии сужу так.
Ему надо чтобы у всех объектов было что-то общее. Например Align.
И он потом делает так:
Объект1.Align := alClient;
И все остальные объекты говорят - ага, мысль! И тоже делают себя на всю область.
Но это телепатия - наука неточная. :-)
← →
Digitman (2003-07-17 09:06) [4]
> Димыч
именно у нескольких ? или у всех объектов дан.класса ?
если у всех, то все достаточно просто
TCommonClass=class
protected
function GetCmnProp: Integer;
procedure SetCmnProp(const Value: Integer);
public
property CmnProp: integer read GetCmnProp write SetCmnProp;
end;
...
var
iProp: Integer;
...
function TCommonClass.GetCmnProp: Integer;
begin
Result := iProp;
end;
procedure TCommonClass.SetCmnProp(const Value: Integer);
begin
iProp := Value;
end;
← →
Digitman (2003-07-17 09:09) [5]ах разных классов, оказывается ! пардон, не обратил внимания)
ну а эти разные классы не имеют общего предка, надо понимать ?
← →
Skier (2003-07-17 09:13) [6]>Димыч (16.07.03 23:34)
Проблема не совсем понятна...
Может быть имеется в виду множественное наследование ?
← →
DiamondShark (2003-07-17 10:41) [7]А какие проблемы? Реализуйте IDispatch и вперёд! Через позднее связывание.
← →
АлексейК (2003-07-17 12:16) [8]Есть понятие делегирования.
Например на форме 10 кнопок TButton
Описываеш ствойство OnClick у одной и присваешь отстальным.
Button2.OnClick:=Button1.OnClik;
....
ButtonX.OnClick:=Button1.OnClik;
У всех кнопок появляется общий обработчик.
← →
Skier (2003-07-17 12:24) [9]>АлексейК (17.07.03 12:16)
А это называется "делегированием" ?
← →
VD602 (2003-07-17 12:46) [10]По-моему, вам нужен class function.
← →
_Nicola_ (2003-07-17 12:58) [11]2Skier © (17.07.03 12:24)
А как это еще может называться?
← →
Skier (2003-07-17 13:02) [12]>_Nicola_ (17.07.03 12:58)
Вряд ли "делегированием"...
← →
Palladin (2003-07-17 14:13) [13]
> _Nicola_ (17.07.03 12:58)
это называется наследованием...
то что я выше привел...
← →
Palladin (2003-07-17 14:14) [14]фу... не обращайте внимания на предыдущее... ступил..
← →
Palladin (2003-07-17 14:18) [15]http://blues.franko.lviv.ua/faculty/pmi/books/Oop_rsis/GLAVA~38.HTM
← →
хм (2003-07-17 14:44) [16]DiamondShark © (17.07.03 10:41)
?А почему не через IInterface?
← →
АлексейК (2003-07-17 15:01) [17]> Skier ©
П. Дарахвелидцзе, Е. Марков Delhpi 4
Делегирование - присвоение реакций на событие одного объекта другому.
← →
Димыч (2003-07-17 22:22) [18]Спасибо всем за советы. А я уточню вопрос и приведу пример. Пусть есть два объекта разных классов: ObA и ObB (общий предок для всех один - TObject :-) ), у объекта ObА есть свойство А, у объекта ObB, тоже есть свойство A. Надо сделать эти свойства общими, с помощью некой функции. После чего инструкция ObA.A := 1, должна вызывать ObB.A := 1; Причем, это обобщение должно происходить динамически... Надеюсь, теперь я ясно выразился?
← →
Palladin (2003-07-17 23:02) [19]думаю все равно тебе необходимо создатьт класс предок всех твоих классов в которую ты хочешь включить эту фичу... этот класс предок будет содеражать не информативное поле, а ссылку на структуру которую ты хочешь сделать общей, а также методы для взятия и установки у него этого указателя...
в результате у тебя может быть 10 объектов разных классов унаследованых от предка и всего лишь 2 реальных общих, между какимилибо из этих объектов, структур
← →
Fantasist. (2003-07-18 00:08) [20]
> После чего инструкция ObA.A := 1, должна вызывать ObB.A
> := 1
Если именно в такой постановке, то можно:
1. Через RTTI, если свойство published.
2. Иначе, сделать у этих двух классов сделать общего предка,
либо определить интерфейс, который эти классы будут реализовывать.
И в том и другом случае надо иметь глобальный список объектов хранящих связанные объекты и функцию SetA для свойства А, которая будет вызывать функцию устанавливание свойства А. Через базовый класс это будет реализоватьт проще всего.
← →
Думкин (2003-07-18 05:07) [21]Все-таки права Наталья - пора меня на костер за колдовство. Угадал ведь. :-)
← →
Димыч (2003-07-18 22:27) [22]
>Palladin ©
> этот класс предок будет содеражать не информативное поле,
> а ссылку на структуру которую ты хочешь сделать общей
речь идет о переопределении указателей на структуры, но как быть со свойствами этих структур?
>Fantasist.
> глобальный список объектов хранящих связанные объекты
это как?
>Думкин ©
> Все-таки права Наталья
Какая еще Наталья?!
__________________________________________________________
Жаль, что "законно" нельзя напрямую добираться до свойств и переопределять их адреса.
← →
Palladin (2003-07-19 10:43) [23]
> Димыч (18.07.03 22:27)
а какие проблемы со свойствами?
type
PMyRec=^TMyRec;
TMyRec=record
s:string;
i:integer;
end;
TClass1=class
private
Rec1:PMyRec;
procedure lcSetRecord(value:TMyRec);
function lcGetRecord:TMyRec;
public
property CmnRec:TMyRec read lcGetRecord write lcSetRecord;
end;
procedure TClass1.lcSetRecord;
begin
Rec1^:=value;
end;
function TClass1.lcGetRecord;
begin
result:=Rec1^;
end;
← →
Palladin (2003-07-19 11:21) [24]Но на самом деле есть и другой путь, ибо указатели на общую структуру это не дело... то есть это конечно выход из ситуации, но он на, какбы это сказать, на не высоком уровне...
В рамках классовой организации можно было бы сотворить следующее...
type
TCmnAncestor=class
protected
m_MemberOf, // Список куда нас добавили
m_Refs:TList; // Список подписаных на присвоение объектов
m_Data:TMyRec; // Общее свойство
procedure lcSetData(value:TMyRec);
public
constructor Create;
destructor Destroy; override;
function IsRefPresent(p_RefClass:TCmnAncestor):boolean; // Проверка на присуствие класса в иерархии подписаных классов
procedure AddRef(p_RefClass:TCmnAncestor); // Добавить к нам в группу подписчиков
procedure AddIn(p_RefClass:TCmnAncestor); // Уведомление о том что нас добавили
procedure Remove(p_RefClass:TCmnAncestor); // Удалить освобождаемый объект из всех списков..
property Data:TMyRec read m_Data write lcSetData;
end;
Constructor TCmnAncestor.Create;
begin
m_Refs:=TList.Create;
m_MemberOf:=TList.Create;
end;
Destructor TCmnAncestor.Destroy;
var
i:integer;
begin
for i:=0 to m_MemberOf.Count-1 do
TCmnAncestor(m_MemberOf[i]).Remove(Self);
m_MembersOf.Free;
m_Refs.Free;
end;
procedure TCmnAncestor.AddRef;
begin
if not IsRefPresent(p_RefClass) then m_Refs.Add(p_RefClass);
end;
procedure TCmnAncestor.AddIn;
begin
m_MemberOf.Add(p_RefClass);
end;
procedure TCmnAncestor.Remove;
begin
repeat until m_Refs.Remove(p_RefClass)=-1;
repeat until m_MemberOf.Remove(p_RefClass)=-1;
end;
procedure TCmnAncestor.lcSetData;
var
i:integer;
begin
m_Data:=Value;
for i:=0 to m_Refs.Count-1 do
TAncestorClass(m_Refs[i]).Data:=Value;
end;
function TCmnAncestor.IsRefPresent;
begin
result:=true;
if m_Refs.IndexOf(p_RefClass)<>-1 then exit else
for i:=0 to m_Refs.Count-1 do
begin
result:=TCmnAncestor(m_Refs[i]).IsRefPresent(p_RefClass);
if result then exit;
end;
result:=false;
end;
остальное дело техники, создавай наследников и вперед...
писал здесь...
может даже есть такой шаблон проектирования, только я о нем не в курсях...
сори за возможные ошибки...
← →
Юрий Зотов (2003-07-19 13:38) [25]> Димыч (17.07.03 22:22)
> Пусть есть два объекта разных классов: ObA и ObB (общий предок
> для всех один - TObject :-) ), у объекта ObА есть свойство А,
> у объекта ObB, тоже есть свойство A. Надо сделать эти свойства
> общими, с помощью некой функции. После чего инструкция
> ObA.A := 1, должна вызывать ObB.A := 1; Причем, это обобщение
> должно происходить динамически... Надеюсь, теперь я ясно
> выразился?
Теперь ясно. Поэтому можно предложить и вариант решения.
type
TMyObject = class
private
FA: integer;
function GetA: integer;
procedure SetA(const Value: integer);
public
property A: integer read GetA write SetA;
end;
var
CommonProperty: boolean = False;
implementation
var
CommonValue: integer = 0;
function TMyObject.GetA: integer;
begin
if CommonProperty then Result := CommonValue else Result := FA
end;
procedure TMyObject.SetA(const Value: integer);
begin
if CommonProperty then CommonValue := Value else FA := Value
end;
Теперь при CommonProperty = True все потомки TMyObject (сколько бы их ни было создано) будут иметь одно и то же значение свойства A, а при CommonProperty = False - каждый свое. Причем управлять этим можно динамически, просто меняя CommonProperty.
← →
Fantasist (2003-07-20 07:42) [26]
> Юрий Зотов © (19.07.03 13:38)
Ну, это уже предложил Digitman ©, однако, это не совсем удовлетворяет условию запроса, так как ObA.A := 1, должна вызывать ObB.A := 1. То есть вполне возможно, что требуется вызвать ObB.SetA().
← →
vidiv (2003-07-20 07:50) [27]
> Юрий Зотов © (19.07.03 13:38)
А без внешних переменных нельзя обойтись?
Страницы: 1 вся ветка
Форум: "Потрепаться";
Текущий архив: 2003.08.07;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.009 c