Inherited & sur-sur-classe [Résolu]

Messages postés
1015
Date d'inscription
samedi 25 octobre 2003
Dernière intervention
29 août 2013
- - Dernière réponse : Guillemouze
Messages postés
1015
Date d'inscription
samedi 25 octobre 2003
Dernière intervention
29 août 2013
- 31 juil. 2006 à 14:51
salut a tous, un question me turlupine :
est il possible de sauter une classe lors d'un appel inherited?
un exemple sera plus clair: j'ai 3 classes qui contiennent toute les 3 une meme methode, et je voudrais que l'inherited de la dernier appele la 1ere.

    TC1 = class
       function fnc: integer; virtual;
    end;

    TC2 = class(TC1)
       function fnc: integer; override;

    end;

   

    TC3 = class(TC2)

       function fnc: integer; override;


    end;

   function TC1.fnc: integer;

       Result := 1;
    end;

   function TC2.fnc: integer;
       Result := inherited fnc;
       Result := Result + 2;
    end;

   function TC3.fnc: integer;

       Result := inherited fnc;

       Result := Result + 3;

    end;

Le pb, c'est que je veux que la fnc de TC3 herite de TC1, mais il faut aussi que les autres methodes de TC3 heritent elles de TC2 !!!
donc j'ai pense a plusieurs solutions pou implementer TC3.fnc:

   function TC3.fnc: integer;


       Result := inherited TC1.fnc;


       Result := Result + 3;


    end;// compile pas

   function TC3.fnc: integer;



       Result := TC1(self).fnc;



       Result := Result + 3;



    end;// boucle infinie (c'est la methode de TC3 qui est appelée)

J'ai pensé a une autre solution qui serait de faire une classe intermediaire, mais je prefererai faire sans. Un truc du genre

    TC1 = class

       function fnc: integer; virtual;

    end;


    TC23 = class(TC1)
       //ici les fonction de TC2 dont TC3 doit heriter ( pas fnc)
    end;

    TC2 = class(TC23)

       function fnc: integer; override;


    end;


   


    TC3 = class(TC23)


       function fnc: integer; override;



    end;

Voila en gros mon probleme.
Merci de votre aide
Afficher la suite 

Votre réponse

6 réponses

Meilleure réponse
Messages postés
424
Date d'inscription
mardi 3 janvier 2006
Dernière intervention
26 novembre 2013
3
Merci
Salut,


"Sauter une classe avec inherited" ? Je ne pense pas que cela soit possible. Ceci dit, il y a un moyen très simple de résoudre ton problème en ajoutant une fonction dans TC1.

  TC1 = class
  protected
     function GetValue: integer; // fonction qui va faire le gros du travail
     function fnc: integer; virtual;
  end;


  TC2 = class(TC1)
  protected
     function fnc: integer; override;
  end;


  TC3 = class(TC2)
  protected
     function fnc: integer; override;
  end;

  function TC1.GetValue: integer;
  begin
     Result := 1;
  end;


  function TC1.fnc: integer;
  begin     Result:GetValue;    // 1
  end;


  function TC2.fnc: integer;
  begin     Result :GetValue + 2;    // 3
  end;


  function TC3.fnc: integer;
  begin     Result :GetValue + 3;     // 4
  end;

A +
Thierry

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 96 internautes nous ont dit merci ce mois-ci

Commenter la réponse de ThWilliam
Messages postés
424
Date d'inscription
mardi 3 janvier 2006
Dernière intervention
26 novembre 2013
3
Merci
Salut.

Je me doute bien que ta fonction est plus compliquée !!! Je ne faisais que reprendre ton exemple simplifié. Le tout est de disposer dans la classe de base d'une méthode qui fait tout le traitement que tu veux mais qui n'est appelée qu'indirectement (sans faire d'override et sans clause inherited : sinon tu crées une chaine d'héritage) et c'est la méthode qui l'utilise qui est surchargée. Voici un exemple avec une propriété en lecture seule (Myprop) qui  emploie un getter (GetMyProp) qui est surchargé dans les classes dérivées.

TC1 = class
  protected
     function Traitement: integer; 
     function GetMyProp: integer; virtual;
  published
     property MyProp: integer read GetMyProp;
  end;


  TC2 = class(TC1)
  protected
     function GetMyProp: integer; override; 
  published
     property MyProp;
  end;


  TC3 = class(TC2)
  protected
     function GetMyProp: integer; override;
  published
     property MyProp;
  end;

 function TC1.Traitement: integer;
  begin
     // traitement aussi compliqué que tu veux
    Result:= ...
  end;


  function TC1.GetMyProp: integer;
  begin
     Result:= Traitement;  // au niveau de TC1 le getter n'ajoute rien au traitement
  end;


  function TC2.GetMyProp: integer;
  begin
     Result := inherited Traitement;
     // code spécifique ajouté pour la classe TC2
     Result:= ...
  end;


  function TC3.GetMyProp: integer;
  begin
     Result := inherited Traitement;
     // code spécifique ajouté pour la classe TC3
    Result:= ...
  end;

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 96 internautes nous ont dit merci ce mois-ci

Commenter la réponse de ThWilliam
Messages postés
4229
Date d'inscription
vendredi 23 juillet 2004
Dernière intervention
3 août 2018
3
Merci
Salut,


Voici une autre méthode :


    TC1 = class
       function fnc: integer; virtual;
    end;


    TC2 = class(TC1)
       function fnc: integer; override;
    end;




    TC3 = class (TC2)
       function fnc: integer; override;
    end;

implementation




{ TC1 }




function TC1.fnc: integer;
begin
  Result : = 1;
end;




{ TC2 }




function TC2.fnc: integer;
begin
  Result := inherited fnc;
  Result := Result + 2;
end ;




{ TC3 }




function TC3.fnc: integer;
Var aC1 : TC1;
begin  
// Comme on ne peut pas sauter une Classe on fait appel à elle directement
  aC1 : = TC1.Create;
  Try
    Result := aC1.Fnc;
  Finally
    aC1.Free;
  End;
  Result : = Result + 3;
end;




{ Démo }




procedure TForm1.Button1Click(Sender: TObject);
Var C1 : TC1;
    C2 : TC2;
    C3 : TC3;
begin
  C1 := TC1.Create;
  C2 := TC2.Create;
  C3 := TC3.Create;
  Try
    Label1.Caption : = IntToStr(C1.Fnc);
    Label2.Caption := IntToStr(C2.Fnc);
    Label3.Caption := IntToStr(C3.Fnc);
  Finally
    C1.Free;
    C2.Free;
    C3.Free;
  End;
end;


C'est pas la plus élégante des méthodes mais elle fonctionne ... tout comme celle de ThWilliam et celle de Neko, d’ailleurs.














@+
Cirec

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 96 internautes nous ont dit merci ce mois-ci

Commenter la réponse de Cirec
Messages postés
1015
Date d'inscription
samedi 25 octobre 2003
Dernière intervention
29 août 2013
0
Merci
merci, mais ca minteresse pas trop, tu pense bien que ma fonction est un poil plus compliquee.

je crois que je vais opter pour une classe abstraite intermediaire, si personne n'a d'autre solution...
Commenter la réponse de Guillemouze
Messages postés
135
Date d'inscription
jeudi 14 août 2003
Dernière intervention
12 octobre 2006
0
Merci
si tu ne tien pas particulièrement au polymorphisme sur cette fonction tu peux toujours faire sans le virtual:

TC1 = class

function fnc: integer;

end;

TC2 = class(TC1)

function fnc: integer;

end;

TC3 = class(TC2)

function fnc: integer;

end;

function TC1.fnc: integer;

Begin

Result := 1;

end;

function TC2.fnc: integer;

Begin

Result := inherited fnc;

Result := Result + 2;

end;

function TC3.fnc: integer;

Begin

Result := TC1(self).fnc;

Result := Result + 3;

end;
Commenter la réponse de cs_neko
Messages postés
1015
Date d'inscription
samedi 25 octobre 2003
Dernière intervention
29 août 2013
0
Merci
ouais jy ai pensé aussi mais c pas tres tres propre, et vu que mes classes sont assez complexes (ce sont des objets geometriques pleins de proprietes et methodes avec de l'heritage en veu tu en voila), la fonction fnc se base sur les champs de l'objet, et je ne peu pas cree d'obet TC1 correspondant au TC3 avec les memes prprietes.
J'ai donc choisi d'inclure une surclasse commune a TC2 et TC3.

merci de votre aide en tout cas :)
Commenter la réponse de Guillemouze

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.