Форум: "Основная";
Текущий архив: 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