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

Вниз

Объектно-ориентированная технология   Найти похожие ветки 

 
Димыч   (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;
Скачать: CL | DM;

Наверх




Память: 0.54 MB
Время: 0.013 c
14-20685
Andryk
2003-07-23 10:00
2003.08.07
Просто прикол :о))


14-20750
vidiv
2003-07-20 07:37
2003.08.07
Есть предложение придумать новый язык


1-20579
andrey__
2003-07-16 13:41
2003.08.07
ServiceApplicetion вызывающая приложение (не видна форма)


1-20613
Buffoon
2003-07-24 19:35
2003.08.07
выделение строки в StringGrid


8-20637
bkv
2003-04-15 11:15
2003.08.07
Вывод текста в Графическом редакторе