Instanciation ou cast a partir du classname

Guillemouze Messages postés 991 Date d'inscription samedi 25 octobre 2003 Statut Membre Dernière intervention 29 août 2013 - 4 avril 2006 à 10:17
cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 - 4 avril 2006 à 14:41
salut
alors voila ce que je voudrai faire:
j'ai une classe Tancetre, et 2 classes Tfils1, Tfils2
et 3 procedure
mafonction(val:Tancetre)

mafonction(val:Tfils1)

mafonction(val:Tfils2)


la fonction qui est appelée est toujours la premier (Tancetre)
le probleme, c que je voudrai faire appel a une correspondant au vrai type du parametre.
donc j'aurai besoin d'une methode permettant de caster val grace a son classname, sans avoir a faire
if val.classname = Tfils1 then mafonction(Tfils1(val));
if val.classname = Tfils2 then mafonction(Tfils2(val));

merci de votre aide

3 réponses

cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 32
4 avril 2006 à 14:41
En utilisant les avantages du polymorphisme, tu n'es pas obligé de déclarer autant de fonctions que de types d'objet à passer en paramètre.

Pour cela, au niveau de la classe TAncetre, déclare les méthodes que tu appelleras en les spécifiant comme virtuelles :

unit Unit2;

interface

uses
  Dialogs;
  
type
  TAncetre =  class
  public
     procedure  Hello;virtual; //important !
  end;

  TFils1  = class(TAncetre)
  public
    procedure Hello;override; //puis surcharge les méthodes des descendants
  end;

  TFils2 =   class (TAncetre)
  public
    procedure Hello;override;
  end;

implementation

{ TAncetre }

procedure TAncetre.Hello;
begin
  ShowMessage('T''as le bonjour de ' + ClassName);
end;

{ TFils1 }

procedure TFils1.Hello;
begin
  ShowMessage('T''as le bonjour de ' + ClassName + ', fils de ' + ClassParent.ClassName);
end;

{ TFils2 }

procedure TFils2.Hello;
begin
  ShowMessage('T''as le bonjour de ' + ClassName + ', fils de ' + ClassParent.ClassName);
end;

end.

Au niveau de l'utilisation de ces classes, tu ne déclares qu'une fonction acceptant un TAncetre en argument :

procedure SayHello(AClass: TAncetre);
begin
  AClass.Hello;
end;

Puis, les appels se font comme de si rien était :

procedure TForm1.Button1Click(Sender: TObject);
var
  Ancetre: TAncetre;
  Fils1: TFils1;
  Fils2: TFils2;
begin
  Ancetre : = Tancetre.Create;
  SayHello(Ancetre);
  Ancetre.Free;

  Fils1 :=  TFils1.Create;
  SayHello(Fils1);
  Fils1.Free;

  Fils2 := TFils2.Create;
  SayHello(Fils2);
  Fils2.Free;
 end ;

Du fait que la méthode dans la classe de base a été déclarée virtuelle, ce seront les méthodes des types réels à l'exécution qui seront appelées.

May Delphi be with you !

<HR color =#008000>
Pensez à cliquer sur Réponse acceptée lorsque la réponse vous convient.
1
cs_neko Messages postés 135 Date d'inscription jeudi 14 août 2003 Statut Membre Dernière intervention 12 octobre 2006 1
4 avril 2006 à 11:43
Il te suffit de mettre "Overload;" à la fin du prototype de ta fonction. delphi fera la selection de la "bonne" fonction a utiliser seul.

Procedure maFonction(A: Tancetre); Overload;
Procedure maFonction(A: TF1); Overload;
Procedure maFonction(A: TF2); Overload;

var
Form1: TForm1;

implementation

{$R *.dfm}

Procedure maFonction(A: Tancetre);
Begin
ShowMessage('A');
End;
Procedure maFonction(A: TF1);
Begin
ShowMessage('F1');
End;
Procedure maFonction(A: TF2);
Begin
ShowMessage('F2');
End;

procedure TForm1.FormCreate(Sender: TObject);
Var
a: TAncetre;
f1: TF1;
f2: Tf2;
begin
a:=TAncetre.Create;
f1:=Tf1.Create;
f2:=Tf2.Create;

maFonction(A);
maFonction(f1);
maFonction(f2);
end;

Pour info il faut éviter les choses du style if val.classname = Tfils1 then si tu veux tester le type d'un objet utilise de préférence l'opérateur is : if val is Tfils1 Then...
0
Guillemouze Messages postés 991 Date d'inscription samedi 25 octobre 2003 Statut Membre Dernière intervention 29 août 2013 6
4 avril 2006 à 12:03
heu c pas tout a fait ca. en fait, g un objet (Tfils1 ou Tfils2) que je passe en tant que Tancetre.

Procedure maFonction(A: Tancetre); Overload;
Procedure maFonction(A: TF1); Overload;
Procedure maFonction(A: TF2); Overload;

var
Form1: TForm1;

implementation

{$R *.dfm}

Procedure maFonction(A: Tancetre);
Begin
ShowMessage('A');
End;
Procedure maFonction(A: TF1);
Begin
ShowMessage('F1');
End;
Procedure maFonction(A: TF2);
Begin
ShowMessage('F2');
End;

procedure TForm1.FormCreate(Sender: TObject);
Var
f1, f2: TAncetre;
begin
f1:=Tf1.Create;
f2:=Tf2.Create;

maFonction(f1);//la je veu qu'il appele mafonction(Tf1)
maFonction(f2);//et pas mafonction(Tancetre)
end;
0
Rejoignez-nous