Overload et heritage

Signaler
Messages postés
991
Date d'inscription
samedi 25 octobre 2003
Statut
Membre
Dernière intervention
29 août 2013
-
Messages postés
135
Date d'inscription
jeudi 14 août 2003
Statut
Membre
Dernière intervention
12 octobre 2006
-
salut tout le monde, une question me vient concernant l'heritage et la surcharge.

imaginons la configuration suivante:

T1 = class;
T2 = class(T1);

et 2 fonctions:

procedure proc(param:T1); overload;
procedure proc(param:T2); overload;

et les appels suivant:

var
    v1 : T1;
    v2 : T2;
begin
    v1 := T2.create;
    v2 := T2.create;
    proc(v1); //(A)
    proc(v2); //(B)
end.

lorsque j'appele (A), c'est la procedure de T1 qui est appelee.
lorsque j'appele (B), c'est la procedure de T2 qui est appelee.

ya t il un moyen que les 2 appelent T2?

5 réponses

Messages postés
135
Date d'inscription
jeudi 14 août 2003
Statut
Membre
Dernière intervention
12 octobre 2006
1
Tu peux caster V1 en T2

var

v1 : T1;

v2 : T2;

begin

v1 := T2.create;

v2 := T2.create;

proc(T2(v1)); //(A) ou proc((v1 as t2));

proc(v2); //(B)

end.

bouh
Messages postés
991
Date d'inscription
samedi 25 octobre 2003
Statut
Membre
Dernière intervention
29 août 2013
7
justement, c'est ce que je veux pas, je veux pas faire un test a chaque fois pour caster. c'est ce que j'ai en ce moment. je voudrais faire autrement.
En fait j'ai une dizaine de classes qui heritent de la classe mere, et je veux que ca fasse appel à la methode correspondant a une des sous classes si elle existe, et sinon appeler la methode correspondant à la classe mere.
voici plus de precisions:
classe mere CM
10 classes C1..C10 heritant de CM
dans chaque sous classe C1..C10, j'ai des methodes correspondant a certaines des autres classes. par exemple, j'ai la classe C1 qui a les procedures:
proc(C1);
proc(C3);

proc(C5);

proc(C6);

proc(C9);

proc(CM); //celle ci doit etre appelee si le parametre n'est ni C1 ni C3 ni C5 ni C6 ni C9.
Messages postés
135
Date d'inscription
jeudi 14 août 2003
Statut
Membre
Dernière intervention
12 octobre 2006
1
Ha ok, j'avais pas capté que tu voulais ça avec des méthodes ( ton exemple le montrait pas du tout ) ^^

A ce moment-là il faut que tu utilise les directives Virtual et Override

La directive Virtual sert en gros ( en très gros même ) à dire que la
méthode donnée sera définie en fonction du constructeur et pas de la
class de déclaration.

La directive Override sert (toujours en gros) a surcharger une méthode virtual ( ou dynamic )


Un exemple sera plus parlant:

TClassMere=Class(TObject)

  Public

    Procedure Proc; Virtual;

End;


TClassFille=Class(TClassMere)

    Public

       Procedure Proc; Override;

End:


Var

  V: TClassMere;

Begin

  V:=TClassFille.Create;

  V.Proc; // Appel TClassFille.Proc;

End;

bouh
Messages postés
991
Date d'inscription
samedi 25 octobre 2003
Statut
Membre
Dernière intervention
29 août 2013
7
merci, mais ca je le sais deja

bon je vais essayer de faire on ne peu plus clair.

type
    TPere = class;
    TFils1 = class;
    TFils2 = class;
    TFils3 = class;
    TFils4 = class;

    TPere = class
    public
       //distribuer sert juste a etre appele dans la sous classe,
       //elles ont toutes la meme implementation
       procedure distribuer(param:TPere);virtual; abstract;
    end;

    TFils1 = class(TPere)
    public
       //forcement une methode avec le parametre de la meme classe
       procedure p(param: TFils1); overload;
       //des methodes pour une ou plusieurs des autres TFilsX
       procedure p(param: TFils3); overload;
       //forcement une methode pour la classe TPere
       procedure p(param: TPere);  overload;
       // implementation de distribuer
       procedure distribuer(param:TPere); override;
    end;

    TFils2 = class(TPere)
    public
       procedure p(param: TFils2); overload;
       procedure p(param: TFils3); overload;
       procedure p(param: TFils4); overload;
       procedure p(param: TPere);  overload;
       procedure distribuer(param:TPere); override;
    end;

    TFils3 = class(TPere)
    public
       procedure p(param: TFils1); overload;
       procedure p(param: TFils3); overload;
       procedure p(param: TPere);  overload;
       procedure distribuer(param:TPere); override;
    end;

    TFils4 = class(TPere)
    public
       procedure p(param: TFils1); overload;
       procedure p(param: TFils3); overload;
       procedure p(param: TPere);  overload;
       procedure distribuer(param:TPere); override;
    end;

procedure TFilsX.distribuer(param: TPere);

begin

    self.p(param);

end;

point important : si une classe fils A n'a pas de procedure pour un autre fils B, alors B a la procedure pour A
par exemple, si il n'y a pas TFils2.p(param:TFils3), alors il y a TFils3.p(param:TFils2)
donc les procedures dont le parametre est TPere sont comme ca:

procedure TFilsX.p(param: TPere);
begin
    param.distribuer(self);
end;

et mon probleme et que quel que soit le type de parametre que je lui passe, il appele toujours la methode p(param:TPere).

var
    p1, p2 : TPere;
    v1 : TFils1;
    v2: Tfils2;
begin
    p1 := TFils1.create;
    v1 := TFils1.create;


    p2 := TFils2.create;
    v2 := TFils2.create;

    //tout ces appels appelent la methode TFils1.distribuer(TPere);
    p1.distribuer(p1);


    p1.distribuer(p2);


    p1.distribuer(v1);


    p1.distribuer(v2);

    v1.distribuer(p1);


    v1.distribuer(p2);


    v1.distribuer(v1);


    v1.distribuer(v2);
end.

je t'envoie la source par pm.

merci
Messages postés
135
Date d'inscription
jeudi 14 août 2003
Statut
Membre
Dernière intervention
12 octobre 2006
1
Bon, désolé, mais là honnetement j'vois pas en suivant ton truc...

Et en y repensant j'ai eu un problème similaire recemment ( je n'ai pas encore trouvé de solution non plus ^^ ) 

Perso j'aurais sans doutes fait: 

TPere=Class

  Procedure Intersection(p: TFils1); Overload; Virtual;

  Procedure Intersection(p: TFils2); Overload; Virtual;

  Procedure Intersection(p: TFils3); Overload; Virtual;

  Procedure Intersection(p: TFils4); Overload; Virtual; 

End;


TFils1=Class(TPere)

  Procedure Intersection(p: TFils1); Overload; Override;

  Procedure Intersection(p: TFils2); Overload; Override;

  Procedure Intersection(p: TFils3); Overload; Override;

  Procedure Intersection(p: TFils4); Overload; Override; 

End;


TFils2=Class(TPere)

  Procedure Intersection(p: TFils2); Overload; Override;

  Procedure Intersection(p: TFils3); Overload; Override;

  Procedure Intersection(p: TFils4); Overload; Override;

End; 


TFils3=Class(TPere)

  Procedure Intersection(p: TFils3); Overload; Override;

  Procedure Intersection(p: TFils4); Overload; Override;

End;


TFils4=Class(TPere)

  Procedure Intersection(p: TFils4); Overload; Override; 

End;


implementation

Procedure TPere.Intersection(p: TFils1);

Begin

  p.Intersection(self);

End;

Procedure TPere.Intersection(p: TFils2);

Begin

  p.Intersection(self);

End;

Procedure TPere.Intersection (p: TFils3);

Begin

  p.Intersection(self);

End;

Procedure TPere.Intersection(p: TFils4);

{ soit ça }

Begin

  p.Intersection(self);

End;

{ soit, si tu veux reduire un peu le code généré:

asm

   jmp TPere.Intersection; //Avec ou sans paramètre, procedure ou fonction c'est pareil

End; }

//============================\\


bref, ne pas mettre machinchose( p: TPere ) parceque c'est ça qui te bloque :/
(juste le recopiage de la discution par mail ^^ )

bouh