FAQ PascalConsultez toutes les FAQ

Nombre d'auteurs : 10, nombre de questions : 401, dernière mise à jour : 5 novembre 2017  Ajouter une question

 

Bienvenue dans la F.A.Q. Pascal !

Celle-ci rassemble les réponses aux questions les plus fréquemment posées sur le langage Pascal et tous ses outils de programmation. Si elle n'a pas pour vocation de répondre à toutes les interrogations possibles, elle reste une bonne base de connaissances sur le Pascal, et ne demande qu'à être enrichie par vos expériences personnelles.

Nous vous invitons à proposer vos propres questions/réponses directement dans la FAQ ou, si vous souhaitez apporter une modification à une question/réponse existante, à la poster dans le fil de discussion renseigné ci-dessous.

Nous vous souhaitons une bonne lecture !

L'équipe Pascal.

Commentez


SommaireLes différents compilateursFree PascalFree Pascal et la Programmation Orientée ObjetLes propriétés (9)
précédent sommaire suivant
 

Une propriété est avant tout un moyen d’accéder à un champ. Cependant, une propriété peut manipuler des méthodes permettant de récupérer une valeur (getter) ou de la fixer (setter).

Les propriétés se servent des mots réservés read et writepour ces accès. Par ailleurs, elles sont déclarées avec l'autre mot réservé property.

Exemple :

Code pascal : Sélectionner tout
1
2
3
4
5
6
7
8
type 
  TMyClass: class 
  private 
     fMyField: Integer; 
     procedure SetMyField(const AInt: Integer); 
  public 
     MyProperty: Integer read fMyField write SetMyField; 
 end;

Mis à jour le 10 août 2016 gvasseur58

Si aucune visibilité n'est déclarée dans une classe, c'est la directive public qui est active.

Soient deux classes déclarées comme suit :

Code pascal : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
type 
  
  TMyClass = class 
  public 
    fMyField: Integer; 
  end;   
  
 TMyOtherClass = class 
   fMyField: Integer; 
  end;

Dans les deux classes, le champ fMyField est de type public.

Mis à jour le 2 septembre 2016 gvasseur58

Un getter est une méthode qui permet de savoir quelles opérations effectuer lorsqu'une tentative de lecture d'une propriété est faite.
Un setter est au contraire une méthode appelée lorsqu'une propriété doit être écrite.

Code pascal : Sélectionner tout
1
2
3
4
5
6
7
8
9
type 
  TMyClass = class 
  strict private 
    fMyField : string; 
    function GetMyField: string; 
    procedure SetMyField(const AValue: string); 
  public 
    property MyField: string read GetMyField write SetMyField; 
  end;

N.B. : les getters et setters ne renvoient pas forcément à un champ.

Mis à jour le 2 septembre 2016 gvasseur58

Contrairement à une variable, une propriété n'occupe pas forcément d'espace en mémoire, car elle n'est pas forcément en rapport avec un champ interne.

On peut par exemple imaginer une propriété en lecture seule qui renverrait un entier tiré au hasard :

Code pascal : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
TMyClass = class 
strict private 
  function GetMyProp: Integer; 
published 
  property MyProp: Integer read GetMyProp; 
end; 
// […] 
implementation 
  
function TMyClass.GetMyProp: Integer; 
// *** renvoie un entier de 0 à 99 *** 
begin 
  Result := Random(100); 
end;

Cette différence en implique d'autres : une propriété ne peut pas servir de paramètre var dans une routine, pas plus que son adresse ne peut être déterminée par @ ou que les procédures comme Inc ou Dec ne peuvent lui être appliquées.

Mis à jour le 2 septembre 2016 gvasseur58

Le spécificateur stored précise si la valeur d'une propriété publiée sera stockée dans le flux de la classe. Il est suivi d'un booléen obtenu grâce à une constante, une fonction sans paramètre ou un champ de la classe. Si elle n'est pas précisée, sa valeur présumée est True.

Code pascal : Sélectionner tout
1
2
3
4
5
6
7
8
type 
  
  TMyClass = class 
  [...] 
  published 
    property MyImage: TImage read fImage write SetImage stored False; 
  [...] 
  end;

Dans l'exemple, la propriété MyImage ne sera pas stockée dans le fichier LFM de la fiche à laquelle elle appartient. L'utilisation du spécificateur évite de sauvegarder des données volumineuses comme une image qui ne serait lue qu'à l'exécution.

Mis à jour le 2 septembre 2016 gvasseur58

Le spécificateur default indique quelle valeur par défaut sera utilisée pour la propriété concernée et qu'il n'est par conséquent pas nécessaire de la stocker dans le flux de la classe. Il prend comme paramètre une constante du même type que la propriété et n'est autorisé que pour les types scalaires et les ensembles.

Code pascal : Sélectionner tout
1
2
3
4
5
6
TMyClass = class  
  [...]  
  published  
    property MyProp : Integer read fMyProp write SetMyProp default 100; 
  [...]  
  end;

La valeur par défaut de MyProp sera 100.

N.B. 1 : Il est de la responsabilité du programmeur d'initialiser la propriété lors de sa création, car le spécificateur ne s'occupe que de l'enregistrement dans le flux et non des initialisations de l'objet instancié.

N.B. 2 : Les autres types comme les chaînes de caractères, les classes ou les réels ont automatiquement une valeur implicite si bien que default ne s'applique pas à eux : les chaînes sont initialisées à la chaîne vide, les classes à nil et les réels à 0.

Mis à jour le 2 septembre 2016 gvasseur58

Le spécificateur nodefault redéfinit une valeur de propriété marquée default sans spécifier de nouvelle valeur. Il est donc utilisé dans une classe descendant d'une classe ayant défini une valeur par défaut pour une propriété particulière.

Code pascal : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
MyClass = class   
  [...]   
  published   
    property MyProp : Integer read fMyProp write SetMyProp default 100;  
  [...]   
  end; 
  
MySubClass = class(TMyClass)   
  [...]   
  published   
    property MyProp : Integer read fMyProp write SetMyProp nodefault;  
  [...]   
  end;

La classe TMySubClass annule la valeur par défaut de 100 attribuée à la propriété MyProp pour lui rendre sa valeur par défaut originelle, à savoir 0.

Mis à jour le 2 septembre 2016 gvasseur58

Lors de la définition d’une sous-classe, une propriété peut de nouveau être déclarée sans en préciser le type. Il est ainsi possible de modifier sa visibilité ou ses spécificateurs : par exemple, une propriété déclarée comme protégée sera de nouveau déclarée dans la section publique ou publiée d’une classe enfant.

Cette technique est très utilisée par des classes qui servent de moules à leurs descendants. Ainsi, le composant TLabel qui est proposé par l’unité stdctrls a-t-il cette déclaration :

Code pascal : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
{ TLabel } 
  
  TLabel = class(TCustomLabel) 
  published 
    property Align; 
    property Alignment; 
    property Anchors; 
    property AutoSize; 
    property BidiMode; 
    property BorderSpacing; 
    property Caption;

Ces propriétés sont en fait définies dans la section protected de l’ancêtre TCustomLabel : l’écriture elliptique property suivi du nom de la propriété héritée signifie simplement que la visibilité de cette dernière change pour devenir published.

Mis à jour le 12 septembre 2016 gvasseur58

Il est possible de lire et d’écrire plusieurs propriétés à partir d’une même méthode à condition qu’elles soient du même type. Dans ce cas, chaque déclaration de type de propriété sera suivie de la directive index elle-même suivie d’un entier précisant le rang de l’index.

Voici la définition possible d'une classe représentant un rectangle :

Code pascal : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
type 
  
  { TMyRect } 
  
  TMyRect = class 
  strict private 
    fValues: array[0..3] of Integer; 
    function GetValue(AIndex: Integer): Integer; 
    procedure SetValue(AIndex: Integer; AValue: Integer); 
  public 
    property Left: Integer index 0 read GetValue write SetValue; 
    property Top: Integer index 1 read GetValue write SetValue; 
    property Width: Integer index 2 read GetValue write SetValue; 
    property Height: Integer index 3 read GetValue write SetValue; 
  end;

L'implémentation du setter et du getter donneront alors :

Code pascal : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
{ TMyRect } 
  
function TMyRect.GetValue(AIndex: Integer): Integer; 
// *** récupération d'une valeur *** 
begin 
  Result := fValues[AIndex]; 
end; 
  
procedure TMyRect.SetValue(AIndex: Integer; AValue: Integer); 
// *** établissement d'une valeur *** 
begin 
  fValues[AIndex] := AValue; 
end;

N.B. : Le getter et le setter sont forcément une fonction et une procédure.

Mis à jour le 12 septembre 2016 gvasseur58

Proposer une nouvelle réponse sur la FAQ

Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour ça


Réponse à la question

Liens sous la question
précédent sommaire suivant
 

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2017 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

 
Responsables bénévoles de la rubrique Pascal : Gilles Vasseur - Alcatîz -