Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Вопрос по RTTI


Страницы:   1 2

sirin ©   (2007-04-18 13:53:00) 

Есть 2 класса


type
 A = class(TPersistent)
 private
   FProp: string;
   function GetProp: string;
   procedure SetProp(const Value: string);
 published
   property prop: string read GetProp write SetProp;
 end;

type
 AB = class(A)
 private
   FProp: string;
   function GetProp: string;
   procedure SetProp(const Value: string);
 published
   property prop: string read GetProp write SetProp;
 end;

function A.GetProp: string;
begin
 result := FProp;
end;

procedure A.SetProp(const Value: string);
begin
 ShowMessage('A');
 FProp := Value;
end;

{ AB }

function AB.GetProp: string;
begin
 result := inherited GetProp;
end;

procedure AB.SetProp(const Value: string);
begin
 ShowMessage('AB');
 inherited SetProp(Value);
end;



Как видно из кода, один класс наследует другой, в первом обьявлено свойство prop, в другом оно перекрыто.

Есть метод, который использует эти классы



procedure TForm1.Button1Click(Sender: TObject);
var
 ObjA: A;
 ObjAB: AB;
begin
 ObjA := A.Create;
 ObjAB := AB.Create;

 SetPropValue(A(ObjAB), 'prop', 'test');

 ObjA.Free;
 ObjAB.Free;
end;


Так вот, несмотря на то, что в параметре я привел обьект класса AB к классу A, при установке свойства у меня все равно срабатывает сеттер класса AB.
Если я устанавливаю свойство обычным способом - A(ObjAB).prop := 'test'; срабатывает сеттер только класса A что мне и нужно.
В чем здесь проблема?


icWasya   (2007-04-19 10:16:00) [1]

>sirin ©   (18.04.07 14:56) [20]
>...........
>Да, все верно
>Но неужели это никак не можно обойти?
Внятно объясни, что же тебе всё-таки нужно?


DimaBr   (2007-04-19 08:39:00) [2]


> Все просто — свойства нельзя перекрыть.

Можно перекрыть медоты чтения и записи свойства. Таким образом имеем "перекрытое свойство".


Kolan   (2007-04-18 22:00:00) [3]

> Как видно из кода, один класс наследует другой, в первом
> обьявлено свойство prop, в другом оно перекрыто.

Все просто — свойства нельзя перекрыть.


DimaBr   (2007-04-18 16:08:00) [4]

От приведения объекта его сущность не изменяется. Глупо было бы если иначе. Привели TDataSet к TForm - получилась новая форма.
В вашем случае нет никакого наследования. Просто одно свойство ЗАКРЫВАЕТдругое.
Указавая A(ObjAB)Prop := 'eee'; вы не приводите к типу а указываете за закрытоесвойство.


oxffff   (2007-04-18 14:57:00) [5]


> Но неужели это никак не можно обойти?


А что грязно?


sirin   (2007-04-18 14:56:00) [6]


> Все отвечаете не на тот вопрос.
> sirin ©   (18.04.07 14:09) [2] >2
> ...
> если я делаю так
> 1)  ObjAB.prop := 'test';
> то одно
> а если так
> 2)  A(ObjAB).prop := 'test';
> то другое
> .............
> У тебя методы SetProp описаны как невиртуальные. Поэтому
> получаются разные результаты.
> Если сделаешь как тут советуют в [7]и[9],
> то операторы 1)и 2) будут выдавать одинаковые результаты.
>
> А процедуры SetPropValue и GetPropValue обращаются к спискам
> свойств, которые виртуальны уже на уровне TObject.
> Поэтому к какому бы типу ты не приводил ObjAB,  операторы
>
> SetPropValue(AB(ObjAB),'prop', 'test');
>
> SetPropValue(A(ObjAB),'prop', 'test');
>
> и подозреваю что даже
> SetPropValue(TObject(ObjAB),'prop', 'test');
>
> будут делать одно и тоже


Да, все верно
Но неужели это никак не можно обойти?


oxffff   (2007-04-18 14:53:00) [7]


> Не работает =(


Оно работает. Только собственно непонятно, что тебе нужно.


Сергей М.   (2007-04-18 14:50:00) [8]


> Это все, что вы можете посоветовать?


А что еще посоветовать тебе, НЕ понимающему ООП-термин "перекрытие" ?


Сергей М.   (2007-04-18 14:47:00) [9]


> sirin


procedure SetPropValue(Instance: TObject; const PropName: string;  const Value: Variant);

Выделенное жирным тебе ни о чем не говорит ?

Видимо - ни о чем.


icWasya   (2007-04-18 14:46:00) [10]

Все отвечаете не на тот вопрос.
sirin ©   (18.04.07 14:09) [2] >2
...
если я делаю так
1)  ObjAB.prop := 'test';
то одно
а если так
2)  A(ObjAB).prop := 'test';
то другое
.............
У тебя методы SetProp описаны как невиртуальные. Поэтому получаются разные результаты.
Если сделаешь как тут советуют в [7]и[9],
то операторы 1)и 2) будут выдавать одинаковые результаты.
А процедуры SetPropValue и GetPropValue обращаются к спискам свойств, которые виртуальны уже на уровне TObject.
Поэтому к какому бы типу ты не приводил ObjAB,  операторы

SetPropValue(AB(ObjAB),'prop', 'test');

SetPropValue(A(ObjAB),'prop', 'test');

и подозреваю что даже
SetPropValue(TObject(ObjAB),'prop', 'test');

будут делать одно и тоже


sirin   (2007-04-18 14:46:00) [11]

Это все, что вы можете посоветовать?
конструкция A(ObjAB).prop или (Obj as A).prop работает корректно.
Вы можете внятно обьяснить, или дать ссылку на "умную книжку" чем использование SetPropValue отличается от этого, и как это можно обойти?
Или все что Вы можете, это давать "умные" советы?


Сергей М.   (2007-04-18 14:41:00) [12]


> sirin ©   (18.04.07 14:36) [13]


Почитать бы ты, барин, книжек умных)

Для ф-ции SetPropValue() твои "приведения типов" по барабану - приведения типов нужны компилятору!


sirin   (2007-04-18 14:36:00) [13]

при вызове SetPropValue(A(ObjAB), 'prop', 'test'); срабатывают сетеры на оба класса


sirin   (2007-04-18 14:35:00) [14]


> oxffff ©   (18.04.07 14:33) [11]
> type
> A = class(TPersistent)
> private
>   FProp: string;
>   function GetProp: string;virtual;
>   procedure SetProp(const Value: string);virtual;
> published
>   property prop: string read GetProp write SetProp;
> end;
>
> type
> AB = class(A)
> private
>   function GetProp: string;override;
>   procedure SetProp(const Value: string);override;
> end;
>
> function A.GetProp: string;
> begin
> result := FProp;
> end;
>
> procedure A.SetProp(const Value: string);
> begin
> ShowMessage('A');
> FProp := Value;
> end;
>
> { AB }
>
> function AB.GetProp: string;
> begin
> result := inherited GetProp;
> end;
>
> procedure AB.SetProp(const Value: string);
> begin
> ShowMessage('AB');
> FProp := Value;
> end;


Не работает =(


oxffff   (2007-04-18 14:33:00) [15]

type
A = class(TPersistent)
private
  FProp: string;
  function GetProp: string;virtual;
  procedure SetProp(const Value: string);virtual;
published
  property prop: string read GetProp write SetProp;
end;

type
AB = class(A)
private
  function GetProp: string;override;
  procedure SetProp(const Value: string);override;
end;

function A.GetProp: string;
begin
result := FProp;
end;

procedure A.SetProp(const Value: string);
begin
ShowMessage('A');
FProp := Value;
end;

{ AB }

function AB.GetProp: string;
begin
result := inherited GetProp;
end;

procedure AB.SetProp(const Value: string);
begin
ShowMessage('AB');
FProp := Value;
end;


sirin   (2007-04-18 14:32:00) [16]


> oxffff ©   (18.04.07 14:28) [7]
> Тебе уже рассказали как сделать
>
> type
> A = class(TPersistent)
> private
>   FProp: string;
>   function GetProp: string;virtual;
>   procedure SetProp(const Value: string);virtual;
> published
>   property prop: string read GetProp write SetProp;
> end;
>
> type
> AB = class(A)
> private
>   FProp: string;
>   function GetProp: string;override;
>   procedure SetProp(const Value: string);override;


Нет, так не работает.
Все равно срабатывают 2 сеттера


oxffff   (2007-04-18 14:29:00) [17]

AB = class(A)
private
 function GetProp: string;override;
 procedure SetProp(const Value: string);override;
end;

:)


sirin   (2007-04-18 14:29:00) [18]

uses TyInfo там есть.
Я думаю вы понимаете, что если бы его не было, компилятор бы сразу ругнулся на то, что он не понимает этот метод. А мой вопрос заключается в другом.


oxffff   (2007-04-18 14:28:00) [19]

Тебе уже рассказали как сделать

type
A = class(TPersistent)
private
  FProp: string;
  function GetProp: string;virtual;
  procedure SetProp(const Value: string);virtual;
published
  property prop: string read GetProp write SetProp;
end;

type
AB = class(A)
private
  FProp: string;
  function GetProp: string;override;
  procedure SetProp(const Value: string);override;
end;


oxffff   (2007-04-18 14:27:00) [20]

А где тогда самое главное uses typinfo?


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо