Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2007.06.17;
Скачать: [xml.tar.bz2];

Вниз

Вопрос по 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.52 MB
Время: 0.056 c
2-1180357011
ambhtr
2007-05-28 16:56
2007.06.17
Цветовой оформление формы


2-1180181459
A Programmer
2007-05-26 16:10
2007.06.17
Не работает копирование в буфер в win9x


15-1179590542
homm
2007-05-19 20:02
2007.06.17
DMClient глюки


2-1180081348
Vitaliy12
2007-05-25 12:22
2007.06.17
ADOQUERY - Где я не прав?


15-1179050104
homm
2007-05-13 13:55
2007.06.17
Я счастлив.





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский