Référence de classe (class of)
Soit une hiérarchie de 3 classes TTrois qui descend de TDeux qui descend de TUn.
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
| unit uTestClassRef;
interface
uses
SysUtils, Windows, Messages, Classes, Graphics, Controls, Forms, Dialogs;
type
TRef2Class = class of TUn;
TUn = class(TObject)
private
FDescription: string;
public
constructor Create;
procedure Afficher; virtual; abstract;
end;
TDeux = class(TUn)
public
constructor Create(D: string = '');
procedure Afficher; override;
end;
TTrois = class(TDeux)
public
constructor Create;
end;
implementation
{
************************************* TUn **************************************
}
constructor TUn.Create;
begin
inherited Create;
FDescription := 'Objet de classe TUn';
end;
{
************************************ TDeux *************************************
}
constructor TDeux.Create(D: string = '');
begin
inherited Create;
FDescription := 'Objet de classe TDeux';
if D <> '' then
FDescription := D;
end;
procedure TDeux.Afficher;
begin
ShowMessage(FDescription);
end;
{
************************************ TTrois ************************************
}
constructor TTrois.Create;
begin
inherited Create('Objet de classe TTrois');
end;
end. |
Je désire les instancier à travers une référence de classe : TRef2Class = class of TUn comme ci-dessous:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
| unit uClassRefTest;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, uTestClassRef, StdCtrls;
type
TfmClassRef = class(TForm)
btnT1parRef: TButton;
btnT2parRef: TButton;
btnT3parRef: TButton;
btnT1Direct: TButton;
btnT2Direct: TButton;
btnT3Direct: TButton;
procedure btnT3DirectClick(Sender: TObject);
procedure btnT2DirectClick(Sender: TObject);
procedure btnT1DirectClick(Sender: TObject);
procedure btnT3parRefClick(Sender: TObject);
procedure btnT2parRefClick(Sender: TObject);
procedure btnT1parRefClick(Sender: TObject);
private
{ Déclarations privées }
procedure TestRef2Class(RC:TRef2Class);
public
{ Déclarations publiques }
end;
var
fmClassRef: TfmClassRef;
implementation
{$R *.dfm}
procedure TfmClassRef.btnT2DirectClick(Sender: TObject);
var
Deux: TDeux;
begin
Deux := TDeux.Create;
try
Deux.Afficher;
finally
Deux.Free;
end;
end;
procedure TfmClassRef.btnT2parRefClick(Sender: TObject);
begin
TestRef2Class(TDeux);
end;
procedure TfmClassRef.btnT3DirectClick(Sender: TObject);
var
Trois: TTrois;
begin
Trois := TTrois.Create;
try
Trois.Afficher;
finally
Trois.Free;
end;
end;
procedure TfmClassRef.btnT3parRefClick(Sender: TObject);
begin
TestRef2Class(TTrois);
end;
procedure TfmClassRef.btnT1DirectClick(Sender: TObject);
var
Un: TUn;
begin
Un := TUn.Create;
try
Un.Afficher;
finally
Un.Free;
end;
end;
procedure TfmClassRef.btnT1parRefClick(Sender: TObject);
begin
TestRef2Class(TUn);
end;
procedure TfmClassRef.TestRef2Class(RC: TRef2Class);
var
IRC: TUn;
begin
IRC := RC.Create;
try
(IRC as RC).Afficher;
finally
IRC.Free;
end;
end;
end. |
Or chaque objet a un constructeur Create qui modifie la valeur d'un champ de TUn.
Or c'est toujours la valeur affectée dans le constructeur de TUn qui est restituée par la méthode Afficher. Les valeurs affectées par les contructeurs de TDeux et TTrois ne sont jamais affectées lorsqu'on instancie ces classes à travers une référence de classe.
Y a-t-il un moyen pour obtenir les messages corrects ?