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

Guillemouze 1015 Messages postés samedi 25 octobre 2003Date d'inscription 29 août 2013 Dernière intervention - 28 juil. 2006 à 14:00 - Dernière réponse : Guillemouze 1015 Messages postés samedi 25 octobre 2003Date d'inscription 29 août 2013 Dernière intervention
- 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
ThWilliam 424 Messages postés mardi 3 janvier 2006Date d'inscription 26 novembre 2013 Dernière intervention - 28 juil. 2006 à 16:45
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

Merci ThWilliam 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 124 internautes ce mois-ci

Commenter la réponse de ThWilliam
Meilleure réponse
ThWilliam 424 Messages postés mardi 3 janvier 2006Date d'inscription 26 novembre 2013 Dernière intervention - 28 juil. 2006 à 19:14
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;

Merci ThWilliam 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 124 internautes ce mois-ci

Commenter la réponse de ThWilliam
Meilleure réponse
Cirec 4224 Messages postés vendredi 23 juillet 2004Date d'inscription 5 juin 2018 Dernière intervention - 31 juil. 2006 à 10:28
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

Merci Cirec 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 124 internautes ce mois-ci

Commenter la réponse de Cirec
Guillemouze 1015 Messages postés samedi 25 octobre 2003Date d'inscription 29 août 2013 Dernière intervention - 28 juil. 2006 à 17:00
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
cs_neko 135 Messages postés jeudi 14 août 2003Date d'inscription 12 octobre 2006 Dernière intervention - 31 juil. 2006 à 00:11
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
Guillemouze 1015 Messages postés samedi 25 octobre 2003Date d'inscription 29 août 2013 Dernière intervention - 31 juil. 2006 à 14:51
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.