Enseignement > Programmation orientée objet > Delphi > Relations entre classes  

I. COMPOSITION D'OBJETS

Un objet peut être composé à partir d'autres objets

Exemple : une voiture est composée

  • de 5 roues (roue de secours) chacune composées
    • d'un pneu
  • d'un moteur composé
    • de plusieurs cylindres
  • de portières
  • etc

Chaque composant est un attribut de l'objet composé

Type TPneu = Class
 
pression : real ;
 
procedure gonfler ;
  
procedure degonfler ;
  constructor TPneu.Create;
end;

TRoue = Class
  
diametre : real ;
  
pneu : TPneu ;
   constructeur TRoue.Create;
   destructor TRoue.free;
end;

TVoiture = Class
  
couleur : TCouleur ;
  
moteur : TMoteur;
  
portieregauche : TPortiere;
  
portieredroite : TPortiere;
  
roueAVG : TRoue;
  
roueAVD : TRoue;
  
roueARG : TRoue;
  
roueARD : TRoue;
  
roueSecours : TRoue;
end;

constructor TPneu.Create;
begin
 
pression := 0 ;
end;

Le constructeur d'un objet composé doit appeler le constructeur de ses composants

constructorr TRoue.Creation;
begin
pneu := TPneu.Creation ;
end ;

constructeur TVoiture.Creation;
begin
moteur := TMoteur.Create ;
portieregauche := TPortière.Create;
portièredroite := TPortiere.Create;
roueAVG := TRoue.Create ;
roueAVD := TRoue.Create ;
roueARG := TRoue.Create ;
roueARD := TRoue.Create ;
roueSecours := TRoue.Create ;
end ;

Le destructeur d'un objet composé doit appeler le destructeur de ses composants

destructor TRoue.free;
debut
pneu.free;
end;

destructor TVoiture.free;
begin
moteur.free;
portieregauche.free;
portieredroite.free;
roueAVG.free;
roueAVD.free;
roueARG.free;
roueARD.free;
end;

L'instanciation d'un objet définit un pointeur sur une zone mémoire

On peut accéder aux composants d'un objet par la notation pointée :

var maVoiture : TVoiture ;
maVoiture := TVoiture.create;
maVoiture.roueAVG.pneu.pression := 100 ;
maVoiture.roueARG.pneu.gonfler;
maVoiture.free;

On peut modifier la référence des objets, simplement par affectation

procedure TVoiture.ChangerRoueAVG ;
var RoueIntervertie : TRoue ;
begin
RoueIntervertie := RoueAVG ; {1}
RoueAVG := RoueSecours ; {2}
RoueSecours := RoueIntervertie ;  {3}
end;

Le paramètre d'une méthode identique à l'attribut d'un objet : ambiguïté de notation

Procedure TRoue.ChangerPneu (pneu :TPneu);
begin
Pneu = pneu ; {????????????}
end

pour lever cette ambiguité, on utilise Self qui désigne l'objet à l'intérieur de ses méthodes

Procedure TRoue.ChangerPneu (pneu :TPneu);
begin
Self.pneu = pneu ;
end;

II. L'HERITAGE DE CLASSES

Classification
ê
distribution systématique en catégories selon des critères précis
ê
hiérarchie des classes

Exemples :

Type Vehicule = Class(Tobject)
 
PosX, PosY, PosZ : real ;
  dX
, dY, dZ : real ;
  
procedure tournerAgauche;
  
procedure tournerAdroite;
 
procedure avancer;
  constructor TVehicule.Create;
end;

TBicyle = Class(TVehicule)
  
Roueavant : TRoue;
  
Rouearriere : TRoue ;
  
procedure freiner;
   constructor TBicycle.Create;
   destructor Tbicycle.free;
end ;

Tvelo = Class(TBicyle)
   Procedure pedaler();
end;

Tmoto = Classe(TBicyle)
  
Carburant : real;
  
Procedure mettre_les_gaz;
end ;

Il faut écrire le constructeur pour les classes qui ont des attributs (initialisation de ces attributs).

L'appel à la méthode inherited déclenche la méthode de l'ancêtre

constructor TVehicule.Create;
begin
  inherited;
  PosX := 0; PosY := 0; PosZ := 0;
  dX := 0; dY := 0; dZ := 0;
end;

constructor TBicycle.Create;
begin
  inherited ;
  Roueavant := TRoue.Create ;
  Rouearriere := Troue.Create;
end;

destructor Tbicycle.free;
begin

  Roueavant.free;
  Rouearriere.free;
  Inherited ;
end;

constructor TMoto.Create;
begin
inherited ;
carburant := 0;
end;

procedure TVehicule.TournerAGauche;
var v : real ;
begin
  v := dx ;
  dx : = -dy ;
  dy := dx ;
end ;

procedure TVehicule.TournerADroite;
var v : real ;
debut
  v := dx ;
  dx : = dy ;
  dy := -dx ;
end;

procedure TVehicule.Avancer;
debut
  posX := posX + dx;
  posY := posY + dy;
 
posZ := posZ + dz;
end;

procedure TVehicule.freiner;
begin
  dx := max(dx-1,0);
  dy := max(dy-1,0);
  dz := max(dz-1,0);
end;

procedure TVelo.pedaler() ;
begin
dx := dx+5;
end;

procedure TMoto.mettre_les_gaz() ;
begin
carburant := carburant 1 ;
dx := dx+20;
end;

var monVelo : Tvelo ;

debut
 
monVelo := TVelo.Create;
 
monVelo.pedaler;
 
monVelo.avancer ;
 
monVelo.tournerAGauche ;
  monVelo.freiner ;
end.

Les méthodes avancer, freiner ou tournerAgauche du vélo ont celles de l'ancêtre.