Existe t il une sorte de polymorphismes pour les membres d'une classe

Résolu
anisb Messages postés 22 Date d'inscription mercredi 16 novembre 2005 Statut Membre Dernière intervention 19 février 2007 - 16 janv. 2007 à 11:13
cs_Loda Messages postés 814 Date d'inscription vendredi 3 novembre 2000 Statut Membre Dernière intervention 30 juillet 2009 - 22 janv. 2007 à 12:13
Je vais expliquer mon probleme et j'espere que je vais pouvoir être precis et comprehensible alors voilà

- j'ai une Classe A de laquelle Hérite deux Classes B et C

- j'ai une classe X de laquelle Hérite deux Classes Y et Z

- La classe A doit a un membre de classe de type X et B et C doivent "caster" ce même membre en type, respectivement Y et Z

- J'ai des traitement à faire par la classe A sur le membre de type X qui est commun à tous ces types

- J'ai des traitement spécifiques par la classe B et C sur leur membres respectifs de type Y et Z


comment feriez vous ??


je ne suis pas sûr d'être trés clair la dessus n'hesitez pas de me poser des questions...

4 réponses

cs_Loda Messages postés 814 Date d'inscription vendredi 3 novembre 2000 Statut Membre Dernière intervention 30 juillet 2009 3
16 janv. 2007 à 12:29
salut,

d'abord je tiens à souligner qu'on (je) apprécie les questions bien posée comme la tienne. Pourrait juste manquer, un p'tit bonjour et ce que tu veux implémenter (l'idée général).

Sinon pour ta question (1er post):

je t'ai popndu un code d'exemple. t'as les grande ligne, adapte le pour tes besoin. Mais avant joue un peu avec p'our bien comprendre qui fait quoi quand.

- cree un nouveau projet
- pose un tmemo et un button
- Copie le code suivant dans l'unité
<hr size="2" width="100%" />

unit uDemo1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

//---------------------------
// pre declaration (comme ça on peut l'utiliser dans C_A)
C_X = class;

C_A = Class(TObject)
private
  Data_C_A  : string;
  Assoc_X : C_X; //liens vers autre class.
  procedure DoIt(mem:TMemo);virtual;
  constructor Create; virtual;
end;

C_B = Class(C_A)
private
  Data_C_B : String;
  procedure DoIt(mem:TMemo);override;
  constructor Create; override;
end;

C_C = Class(C_A)
private
  Data_C_C : string;
  procedure DoIT(mem:TMemo);override;
  constructor Create; override;
end;

//----------------------------------

C_X = Class
private
  Data_C_X : string;
  procedure DoIT(mem:TMemo);virtual;
  constructor Create; virtual;
end;

C_Y = Class(C_X)
private
  Data_C_Y : string;
  Data_C_Y2 : extended;
  procedure DoIT(mem:TMemo);override;
  constructor Create; override;
end;

C_Z = Class(C_X)
private
  Data_C_Z : string;
  Data_C_Z2 : integer;
  procedure DoIT(mem:TMemo);override;
  constructor Create; override;
end;
//-------------------------

var
  Form1: TForm1;

implementation
{$R *.dfm}

{ C_A }

constructor C_A.Create;
begin
  Data_C_A := 'Data de Class A';
  Assoc_X := nil; //pas d'object pour le moment.
end;

procedure C_A.DoIt(mem: TMemo);
begin
  mem.Lines.Add(Data_C_A);

//  Si un object est lié
  if Assigned(Assoc_X) then begin

    // traitement specifique
    // (override de methode : meme goal/usage, mais moyen différent)
    Assoc_X.DoIT(mem);

    // lit les data spécifique
    // (lit les données spéc à la class lieé dynamiquement)
    if Assoc_X is C_Y then
      with Assoc_X as C_Y do begin
        mem.Lines.Add(Format('Y : %f',[Data_C_Y2]));
      end;

    if Assoc_X is C_Z then
      with Assoc_X as C_Z do begin
        mem.Lines.Add(Format('Z : %d',[Data_C_Z2]));
      end;

  end;

end;

{ C_B }

constructor C_B.Create;
begin
  inherited;
  Data_C_B := 'Data de Class B(A)';
end;

procedure C_B.DoIt(mem: TMemo);
begin
  inherited;
  mem.Lines.Add(Data_C_B);
end;

{ C_C }

constructor C_C.Create;
begin
  inherited;
  Data_C_C := 'Data de Class C(A)';
end;

procedure C_C.DoIT(mem: TMemo);
begin
  inherited;
  mem.Lines.Add(Data_C_C);
end;

{ C_X }

constructor C_X.Create;
begin
  Data_C_X := 'subData de C_X';
end;

procedure C_X.DoIT(mem: TMemo);
begin
  mem.Lines.Add(Data_C_X);
end;

{ C_Y }

constructor C_Y.Create;
begin
  inherited;
  Data_C_Y := 'subData de C_Y (C_X)';
  Data_C_Y2 := 3.14;
end;

procedure C_Y.DoIT(mem: TMemo);
begin
  inherited;
  mem.Lines.Add(Data_C_Y);
end;

{ C_Z }

constructor C_Z.Create;
begin
  inherited;
  Data_C_Z := 'subData de C_Z (C_X)';
  Data_C_Z2 := 123;
end;

procedure C_Z.DoIT(mem: TMemo);
begin
  inherited;
  mem.Lines.Add(Data_C_Z);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Ay, Az : C_A;
  Y : C_Y;
  Z : C_Z;
begin
  // cree les object
  Ay := C_A.Create;
  Az := C_A.Create;
  Y := C_Y.Create;
  Z := C_Z.Create;

  // cree les liens
  Ay.Assoc_X := Y;
  Az.Assoc_X := Z;

  //display result
  Memo1.Clear;

  Memo1.Lines.Add('# Ay : ');
  Ay.DoIt(Memo1);

  Memo1.Lines.Add('# Az : ');
  Az.DoIt(Memo1);

  // libere les object
  Y.Free;
  Z.Free;
  Ay.Free;
  Az.Free;

end;

end.
<hr size="2" width="100%" />
les possibilités de liens entre les class sont nombreux. Un choix calme et réfléchit est vital pour bien démarrer un soft.

les liens peuvent être bidirectionel, monodirectionel, un à plusieur, plusieur à un, .... une connaissance de base de la modélisation UML (pas seulement ce que veullent dire les petit dessin) est très utile (voir indispensable). renseigne toi.

bien  maîtrisié le language (delphi) est aussi important (ici on peut t'aider si t'as des questions)

lorsque tu fait des liens de ce type entre des class, fait bien attention quand et qui détruit quoi. (évite les perte de mémoire et les violation d'acces.)

Loda
<hr size="2" width="100%" />Se poser les bonnes questions est le premier pas pour trouver les bonnes réponses.
3
anisb Messages postés 22 Date d'inscription mercredi 16 novembre 2005 Statut Membre Dernière intervention 19 février 2007 1
16 janv. 2007 à 11:33
Voilà je rajoute un petit bout de code

TBaseModule = Class(TForm)
   AffichageResultat : TBaseAffichageResultat;
   Procedure InitAffichage; Virtual // Initialise l'affichage du résultat
End;

TRealAffichageResultat = Class(TBaseAffichageResultat)
  MembreReal : TButton;
  Procedure TraitementReal;
End;

TRealAffichageResultat = Class(TBaseAffichageResultat)
   MembreSimu : TPanel;
   Procedure TraitementSimulation;
End;

TRealModule = Class(TBaseModule)
   AffichageResultat : TRealAffichageResultat;
   Procedure InitAffichage; Override // Initialise l'affichage du résultat pour le mode réel
End;

TSimuModule = Class(TBaseModule)
   AffichageResultat : TSimuAffichageResultat;
   Procedure InitAffichage; Override // Initialise l'affichage du résultat pour le mode simulation
End;
0
anisb Messages postés 22 Date d'inscription mercredi 16 novembre 2005 Statut Membre Dernière intervention 19 février 2007 1
19 janv. 2007 à 10:38
Bonjour,
Bonjour,
Bonjour, (Voilà les trois bonjour des mes trois precedents Posts désolé pour le retard )
Merci Loda, pour avoir pris autant de temps et autant de peine à me répondre...
J'ai eu une autre façon de faire (comme tu le disais il y a plusieurs façon de faire) sur le forum de developpez et je voudrais en faire profiter les autres forumiens. Il s'agit en fait de positionner des Propriétés avec des Getters des Setters sur le membre de classe de base. ainsi on a un acces direct à celle-ci (d'une manière artificielle) par invocation de cette propriété
Merci
0
cs_Loda Messages postés 814 Date d'inscription vendredi 3 novembre 2000 Statut Membre Dernière intervention 30 juillet 2009 3
22 janv. 2007 à 12:13
salut,

le fait que tu utilise des getter et setter pour acceder au champs ne CHANGE RIEN (ou presque) à ta structure de base !!

c'est important que cela soit clair pour toi!

d'avoir

MonLien : TMaClass

ou property MonLien read fMonLien;

c'est la même choses.

cela te permet seulement de faire des clacul/mise à jour / vérification avant de retourner l'object. C'est pratique, par exemple, pour ne créer des object que lors du premier appel

genre
functionTMaClass.GetMonSousObject : TMonSousObject;
begin
  if not assigned(fMonSousObject) then
  fMonSOusOject := TMonSOusObject.Create;

  fMonSousObject.MiseAJour;
  Result := fMonSOusObject;
end;

mais la façon dont tes class sont liée est un autre problème.

note qu'il a surement moyen de faire plus simple que l'explication donnée dans ton premier post, mais ne connaissant pas le context, je ne peux pas te répondre plus précisement. Je me suis contenté de répondre à ta question technique sur les class. t'as surement une bonne strucutre maitenant, mais fait jsute attention à bien comprendre ce que tu fais.

bon code,

Loda
<hr size="2" width="100%" />Se poser les bonnes questions est le premier pas pour trouver les bonnes réponses.
0
Rejoignez-nous