Skip to content

Latest commit

 

History

History
551 lines (444 loc) · 13.5 KB

File metadata and controls

551 lines (444 loc) · 13.5 KB

🔝 Retour au Sommaire

3.7.2 Propriétés et méthodes en Object Pascal

Introduction

Dans la partie précédente, nous avons découvert les classes et objets. Maintenant, nous allons approfondir deux concepts essentiels : les propriétés et les méthodes. Ces éléments permettent de définir ce que nos objets peuvent faire (méthodes) et comment on accède à leurs données (propriétés).

Les méthodes

Qu'est-ce qu'une méthode ?

Une méthode est une fonction ou une procédure qui appartient à une classe. C'est une action que l'objet peut effectuer. Les méthodes définissent le comportement de l'objet.

Types de méthodes

Il existe deux types principaux de méthodes :

1. Les procédures (procedures)

Une procédure est une méthode qui effectue une action mais ne retourne pas de valeur.

type
  TVoiture = class
  private
    FVitesse: Integer;
  public
    procedure Accelerer;
    procedure Freiner;
  end;

procedure TVoiture.Accelerer;  
begin  
  FVitesse := FVitesse + 10;
  ShowMessage('Accélération ! Vitesse : ' + IntToStr(FVitesse) + ' km/h');
end;

procedure TVoiture.Freiner;  
begin  
  if FVitesse > 0 then
    FVitesse := FVitesse - 10;
  ShowMessage('Freinage ! Vitesse : ' + IntToStr(FVitesse) + ' km/h');
end;

2. Les fonctions (functions)

Une fonction est une méthode qui effectue une action et retourne une valeur.

type
  TVoiture = class
  private
    FVitesse: Integer;
    FMarque: string;
  public
    function ObtenirVitesse: Integer;
    function EstALArret: Boolean;
    function ObtenirDescription: string;
  end;

function TVoiture.ObtenirVitesse: Integer;  
begin  
  Result := FVitesse;
end;

function TVoiture.EstALArret: Boolean;  
begin  
  Result := (FVitesse = 0);
end;

function TVoiture.ObtenirDescription: string;  
begin  
  Result := Format('Voiture %s roulant à %d km/h', [FMarque, FVitesse]);
end;

Méthodes avec paramètres

Les méthodes peuvent accepter des paramètres pour modifier leur comportement :

type
  TCalculatrice = class
  public
    function Additionner(A, B: Integer): Integer;
    function Multiplier(A, B: Double): Double;
    procedure AfficherResultat(Valeur: Double; Operation: string);
  end;

function TCalculatrice.Additionner(A, B: Integer): Integer;  
begin  
  Result := A + B;
end;

function TCalculatrice.Multiplier(A, B: Double): Double;  
begin  
  Result := A * B;
end;

procedure TCalculatrice.AfficherResultat(Valeur: Double; Operation: string);  
begin  
  ShowMessage(Format('Résultat de %s : %.2f', [Operation, Valeur]));
end;

Utilisation des méthodes

var
  MaVoiture: TVoiture;
  Calc: TCalculatrice;
begin
  MaVoiture := TVoiture.Create;
  try
    MaVoiture.Accelerer;  // Appel d'une procédure
    MaVoiture.Accelerer;

    if MaVoiture.EstALArret then  // Appel d'une fonction
      ShowMessage('La voiture est arrêtée')
    else
      ShowMessage('Vitesse : ' + IntToStr(MaVoiture.ObtenirVitesse));
  finally
    MaVoiture.Free;
  end;

  Calc := TCalculatrice.Create;
  try
    Calc.AfficherResultat(Calc.Additionner(5, 3), 'addition');
  finally
    Calc.Free;
  end;
end;

Les propriétés

Qu'est-ce qu'une propriété ?

Une propriété est une manière élégante et contrôlée d'accéder aux champs d'une classe. Les propriétés agissent comme des champs publics, mais permettent d'exécuter du code lors de la lecture ou de l'écriture.

Pourquoi utiliser des propriétés ?

Au lieu d'exposer directement les champs privés, on utilise des propriétés pour :

  • Contrôler les valeurs assignées (validation)
  • Calculer des valeurs dynamiquement
  • Déclencher des actions lors de modifications
  • Protéger l'intégrité des données

Syntaxe de base d'une propriété

type
  TPersonne = class
  private
    FNom: string;
    FAge: Integer;
  public
    property Nom: string read FNom write FNom;
    property Age: Integer read FAge write FAge;
  end;

Cette syntaxe signifie :

  • property Nom : déclare une propriété nommée "Nom"
  • read FNom : quand on lit la propriété, on retourne le champ FNom
  • write FNom : quand on écrit dans la propriété, on modifie le champ FNom

Utilisation des propriétés

var
  Personne: TPersonne;
begin
  Personne := TPersonne.Create;
  try
    // Écriture (write)
    Personne.Nom := 'Marie Dubois';
    Personne.Age := 30;

    // Lecture (read)
    ShowMessage('Nom : ' + Personne.Nom);
    ShowMessage('Âge : ' + IntToStr(Personne.Age));
  finally
    Personne.Free;
  end;
end;

Propriétés avec méthodes d'accès

Pour avoir plus de contrôle, on peut utiliser des méthodes spéciales appelées getter et setter :

type
  TCompteBancaire = class
  private
    FTitulaire: string;
    FSolde: Double;
    procedure SetSolde(const Value: Double);
    function GetSoldeFormate: string;
  public
    property Titulaire: string read FTitulaire write FTitulaire;
    property Solde: Double read FSolde write SetSolde;
    property SoldeFormate: string read GetSoldeFormate;
  end;

// Setter : contrôle lors de l'écriture
procedure TCompteBancaire.SetSolde(const Value: Double);  
begin  
  if Value < 0 then
    raise Exception.Create('Le solde ne peut pas être négatif')
  else
    FSolde := Value;
end;

// Getter : calcul lors de la lecture
function TCompteBancaire.GetSoldeFormate: string;  
begin  
  Result := FormatFloat('#,##0.00 €', FSolde);
end;

Utilisation

var
  Compte: TCompteBancaire;
begin
  Compte := TCompteBancaire.Create;
  try
    Compte.Titulaire := 'Jean Martin';
    Compte.Solde := 1500.50;  // Appelle SetSolde

    ShowMessage('Solde : ' + Compte.SoldeFormate);  // Appelle GetSoldeFormate

    // Ceci génèrera une exception
    // Compte.Solde := -100;
  finally
    Compte.Free;
  end;
end;

Propriétés en lecture seule

Une propriété peut être en lecture seule si on omet la partie write :

type
  TCercle = class
  private
    FRayon: Double;
    function GetSurface: Double;
    function GetPerimetre: Double;
  public
    property Rayon: Double read FRayon write FRayon;
    property Surface: Double read GetSurface;  // Lecture seule
    property Perimetre: Double read GetPerimetre;  // Lecture seule
  end;

function TCercle.GetSurface: Double;  
begin  
  Result := Pi * FRayon * FRayon;
end;

function TCercle.GetPerimetre: Double;  
begin  
  Result := 2 * Pi * FRayon;
end;

Utilisation

var
  Cercle: TCercle;
begin
  Cercle := TCercle.Create;
  try
    Cercle.Rayon := 5;

    // Ces propriétés sont calculées automatiquement
    ShowMessage('Surface : ' + FloatToStr(Cercle.Surface));
    ShowMessage('Périmètre : ' + FloatToStr(Cercle.Perimetre));

    // Ceci générerait une erreur de compilation
    // Cercle.Surface := 100;  // Erreur : propriété en lecture seule
  finally
    Cercle.Free;
  end;
end;

Propriétés en écriture seule

Plus rare, mais parfois utile pour définir des paramètres sans pouvoir les relire :

type
  TSysteme = class
  private
    procedure SetMotDePasse(const Value: string);
  public
    property MotDePasse: string write SetMotDePasse;  // Écriture seule
  end;

procedure TSysteme.SetMotDePasse(const Value: string);  
begin  
  // Stocker le hash du mot de passe, pas le mot de passe lui-même
  // (code simplifié)
  ShowMessage('Mot de passe défini avec succès');
end;

Exemple complet : Classe Rectangle

Voici un exemple complet combinant méthodes et propriétés :

type
  TRectangle = class
  private
    FLargeur: Double;
    FHauteur: Double;
    procedure SetLargeur(const Value: Double);
    procedure SetHauteur(const Value: Double);
    function GetSurface: Double;
    function GetPerimetre: Double;
  public
    constructor Create(ALargeur, AHauteur: Double);
    procedure Agrandir(Facteur: Double);
    procedure AfficherInfos;
    function EstCarre: Boolean;

    property Largeur: Double read FLargeur write SetLargeur;
    property Hauteur: Double read FHauteur write SetHauteur;
    property Surface: Double read GetSurface;
    property Perimetre: Double read GetPerimetre;
  end;

constructor TRectangle.Create(ALargeur, AHauteur: Double);  
begin  
  inherited Create;
  SetLargeur(ALargeur);
  SetHauteur(AHauteur);
end;

procedure TRectangle.SetLargeur(const Value: Double);  
begin  
  if Value <= 0 then
    raise Exception.Create('La largeur doit être positive')
  else
    FLargeur := Value;
end;

procedure TRectangle.SetHauteur(const Value: Double);  
begin  
  if Value <= 0 then
    raise Exception.Create('La hauteur doit être positive')
  else
    FHauteur := Value;
end;

function TRectangle.GetSurface: Double;  
begin  
  Result := FLargeur * FHauteur;
end;

function TRectangle.GetPerimetre: Double;  
begin  
  Result := 2 * (FLargeur + FHauteur);
end;

procedure TRectangle.Agrandir(Facteur: Double);  
begin  
  FLargeur := FLargeur * Facteur;
  FHauteur := FHauteur * Facteur;
end;

function TRectangle.EstCarre: Boolean;  
begin  
  Result := (FLargeur = FHauteur);
end;

procedure TRectangle.AfficherInfos;  
var  
  Info: string;
begin
  Info := Format('Rectangle : %.2f x %.2f'#13#10 +
                 'Surface : %.2f'#13#10 +
                 'Périmètre : %.2f',
                 [FLargeur, FHauteur, Surface, Perimetre]);

  if EstCarre then
    Info := Info + #13#10 + 'C''est un carré !';

  ShowMessage(Info);
end;

Utilisation de la classe Rectangle

var
  MonRectangle: TRectangle;
begin
  MonRectangle := TRectangle.Create(5, 3);
  try
    MonRectangle.AfficherInfos;

    // Modifier via les propriétés
    MonRectangle.Largeur := 4;
    MonRectangle.Hauteur := 4;

    MonRectangle.AfficherInfos;

    // Utiliser une méthode
    MonRectangle.Agrandir(2);
    MonRectangle.AfficherInfos;

  finally
    MonRectangle.Free;
  end;
end;

Différence entre champs, propriétés et méthodes

Élément Description Exemple
Champ Variable stockant une donnée FNom: string;
Propriété Interface contrôlée pour accéder à un champ property Nom: string read FNom write FNom;
Méthode Action que l'objet peut effectuer procedure SePresenter;

Quand utiliser quoi ?

  • Champs privés : pour stocker les données internes
  • Propriétés : pour exposer les données de manière contrôlée
  • Méthodes : pour définir des actions ou des calculs

Conventions de nommage

Pour les champs privés

  • Préfixe F : FNom, FAge, FSolde

Pour les propriétés

  • Pas de préfixe : Nom, Age, Solde
  • Même nom que le champ mais sans le F

Pour les méthodes d'accès

  • Getters : préfixe Get : GetNom, GetAge
  • Setters : préfixe Set : SetNom, SetAge

Pour les méthodes publiques

  • Verbes d'action : Calculer, Afficher, Enregistrer
  • Questions (booléens) : Est..., Peut..., A...
type
  TDocument = class
  private
    FTitre: string;
    FModifie: Boolean;
    procedure SetTitre(const Value: string);
  public
    property Titre: string read FTitre write SetTitre;
    property EstModifie: Boolean read FModifie;

    procedure Enregistrer;
    function PeutEtreFerme: Boolean;
    procedure AfficherApercu;
  end;

Bonnes pratiques

  1. Toujours utiliser des propriétés plutôt que des champs publics

    // ❌ Mauvais
    type
      TPersonne = class
      public
        Nom: string;
        Age: Integer;
      end;
    
    // ✅ Bon
    type
      TPersonne = class
      private
        FNom: string;
        FAge: Integer;
      public
        property Nom: string read FNom write FNom;
        property Age: Integer read FAge write FAge;
      end;
  2. Valider les données dans les setters

    procedure TPersonne.SetAge(const Value: Integer);
    begin
      if (Value < 0) or (Value > 150) then
        raise Exception.Create('Âge invalide')
      else
        FAge := Value;
    end;
  3. Utiliser des propriétés en lecture seule pour les valeurs calculées

    property Surface: Double read GetSurface;  // Pas de write
  4. Nommer les méthodes avec des verbes d'action

    procedure Calculer;
    procedure Afficher;
    function Verifier: Boolean;
  5. Garder les méthodes courtes et focalisées

    • Une méthode = une responsabilité
    • Si une méthode est trop longue, la diviser en plusieurs méthodes

Résumé

  • Les méthodes définissent ce que l'objet peut faire (son comportement)

    • Procédures : actions sans valeur de retour
    • Fonctions : actions avec valeur de retour
  • Les propriétés fournissent un accès contrôlé aux données de l'objet

    • read : définit comment lire la propriété
    • write : définit comment écrire dans la propriété
    • Peuvent être en lecture seule, écriture seule, ou lecture/écriture
  • Les getters et setters permettent de contrôler et valider les accès

    • Getter : méthode appelée lors de la lecture
    • Setter : méthode appelée lors de l'écriture
  • Bonnes pratiques :

    • Champs privés avec préfixe F
    • Propriétés publiques sans préfixe
    • Validation dans les setters
    • Méthodes avec des noms descriptifs

Maîtriser les propriétés et méthodes est essentiel pour créer des classes robustes et maintenables en Delphi. Ces concepts permettent l'encapsulation, un principe fondamental de la programmation orientée objet.

⏭️ Héritage et polymorphisme