![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Вопрос по RTTI
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?