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

Вниз

Вопрос по RTTI   Найти похожие ветки 

 
sirin ©   (2007-04-18 13:53) [0]

Есть 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 что мне и нужно.
В чем здесь проблема?


 
Сергей М. ©   (2007-04-18 14:03) [1]


> в другом оно перекрыто.


"перекрыто" - это override, при условии что перекрываемый метод объявлен как virtual.

У тебя же ни тем ни другим даже не пахнет.


 
sirin ©   (2007-04-18 14:09) [2]


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


Если я делаю
ObjA.prop := "test";
то получаю сначала ShowMessage("AB") (сработал сетер класса AB) потом ShowMessage("A") (сработал сетер класса A)

Если я делаю
A(ObjA).prop := "test";
то получаю только ShowMessage("A") (сработал сетер класса A) - что правильно, потому что я привел обьект к классу A

но такое приведение не работает в SetPropValue =(
Он просто не понимает, что я привожу обьект к другому классу =(


 
Сергей М. ©   (2007-04-18 14:13) [3]


> Он просто не понимает, что я привожу обьект к другому классу


И не поймет, пока ты не поймешь принципы полиморфизма в ООП)


 
oxffff ©   (2007-04-18 14:19) [4]

А где здесь RTTI?


 
sirin ©   (2007-04-18 14:21) [5]

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


 
oxffff ©   (2007-04-18 14:27) [6]

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


 
oxffff ©   (2007-04-18 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;
end;


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

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


 
oxffff ©   (2007-04-18 14:29) [9]

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

:)


 
sirin ©   (2007-04-18 14:32) [10]


> 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: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;


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


> 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;


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


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

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


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


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


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

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


 
sirin ©   (2007-04-18 14:46) [15]

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


 
icWasya ©   (2007-04-18 14:46) [16]

Все отвечаете не на тот вопрос.
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");

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


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


> sirin


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

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

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


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


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


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


 
oxffff ©   (2007-04-18 14:53) [19]


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


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


 
sirin ©   (2007-04-18 14:56) [20]


> Все отвечаете не на тот вопрос.
> 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:57) [21]


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


А что грязно?


 
DimaBr ©   (2007-04-18 16:08) [22]

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


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

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

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


 
DimaBr ©   (2007-04-19 08:39) [24]


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

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


 
icWasya ©   (2007-04-19 10:16) [25]

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



Страницы: 1 вся ветка

Текущий архив: 2007.06.17;
Скачать: CL | DM;

Наверх




Память: 0.54 MB
Время: 0.101 c
2-1180303179
Просто_новичок
2007-05-28 01:59
2007.06.17
максимальное количество символов в string


15-1179715558
Slider007
2007-05-21 06:45
2007.06.17
С днем рождения ! 21 мая


1-1176894953
Jioniro
2007-04-18 15:15
2007.06.17
Определение координат


1-1176899250
webpauk
2007-04-18 16:27
2007.06.17
размер иконок


6-1164628055
Yurij-7
2006-11-27 14:47
2007.06.17
LDAP и работа с ним