FAQ PascalConsultez toutes les FAQ
Nombre d'auteurs : 10, nombre de questions : 402, dernière mise à jour : 7 janvier 2018 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.
- Qu'est-ce qu'une propriété en Pascal ?
- Quelle est la visibilité par défaut d'un champ dans une classe ?
- Qu'est-ce qu'un setter et un getter ?
- Quelles différences y a-t-il entre une propriété et une variable ?
- A quoi sert le spécificateur stored ?
- A quoi sert le spécificateur default ?
- A quoi set le spécificateur nodefault ?
- Pourquoi certaines propriétés apparaissent-elles avec une simple déclaration sans type ?
- Qu'est-ce qu'une propriété indexée ?
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; |
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.
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.
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.
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.
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.
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.
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.
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.
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 çaLes 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 © 2024 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.