FAQ PascalConsultez toutes les FAQ

Nombre d'auteurs : 10, nombre de questions : 400, dernière mise à jour : 12 septembre 2016  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 méthodes (12)
précédent sommaire suivant
 

Une méthode décrit des opérations applicables grâce à une classe. Elle est soit une procédure soit une fonction encapsulée dans une classe. L'accès à une méthode suit le schéma suivant :

Code pascal : Sélectionner tout
NomDeLObjet.NomDeLaMethode

Notez que pour être utilisée, une méthode ordinaire doit appartenir à une classe qui a été instanciée. Autrement dit, la première partie de l'expression, celle qui précède le point, doit être un objet valide.

Exemple :
Code pascal : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
  
interface 
  
type 
  TMyClass = class 
    private 
       fMyInt: Integer; 
   public 
      function DoubleInt: Integer; 
      property MyInt: Integer read fMyInt write fMyInt; 
  end; 
  
implementation 
  
function TMyClass.DoubleInt; 
begin 
  Result := MyInt * 2; 
end; 
  
[...] 
  
var 
  MyObject: TMyClass; 
  I: Integer; 
  
[...] 
  MyObject := TMyClass.Create; 
  MyObject.MyInt := 4; 
  I := MyObject.DoubleInt; // I vaut 2 fois 4 = 8 
[...] 
  MyObject.Free;

Mis à jour le 10 août 2016 gvasseur58

Les méthodes comme Free et Create ne sont pas déclarées par vous et vous pouvez cependant les utiliser. Ce phénomène paraît contredire le principe pascalien qui veut que tout identificateur doit être déclaré avant de pouvoir être utilisé.

En fait, toute classe déclarée hérite d'une classe racine baptisée TObject. C'est cette dernière qui déclare et implémente ces méthodes mystérieuses.

Ainsi :

Code pascal : Sélectionner tout
1
2
3
4
type 
  TMyClass = class 
  [...] 
  end;

et :

Code pascal : Sélectionner tout
1
2
3
4
type 
  TMyClass = class(TObject) 
  [...] 
  end;

sont deux écritures équivalentes.

Mis à jour le 10 août 2016 gvasseur58

Les méthodes statiques se comportent comme des procédures ou des fonctions ordinaires à ceci près qu’elles ont besoin d’un objet pour être invoquées. Elles sont dites statiques parce que le compilateur crée les liens nécessaires à leur accès dès la compilation : elles sont ainsi particulièrement rapides, mais manquent de souplesse en se refusant à tout polymorphisme. Pour les utiliser, il suffit de les déclarer, sans autre précision.

Une méthode statique peut être redéfinie dans les classes qui en héritent.

Dans l'exemple suivant, la méthode DoSomething sera statique :

Code pascal : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
type 
  TMyClass = class 
  public 
    procedure DoSomething; 
  end; 
  
[...] 
  
implementation 
  
procedure TMyClass.DoSomething; 
begin 
  Beep; 
  Sleep(200); 
  Beep; 
end;

Mis à jour le 18 août 2016 gvasseur58

Contrairement aux méthodes statiques dont le compilateur détermine directement les adresses au moment de la compilation, les méthodes virtuelles sont accessibles via une table qui porte le nom de VMT (Virtual Method Table, soit table des méthodes virtuelles). C'est elle qui permet de retrouver à l’exécution l'adresse de chacune des méthodes dont la classe a hérité et de celles qu’elle a elle-même définies.

Une méthode virtuelle autorise la mise en œuvre du polymorphisme. Pour la déclarer, il faut faire suivre sa déclaration de la directive virtual. Pour la redéclarer dans une sous-classe, il faut faire suivre sa déclaration de la directive override.

Code pascal : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
type 
  TMyClass = class 
  public 
    MyProc(AValue: string); virtual; 
  end; 
  
  TMySubClass = class(TMyClass) 
  public 
    MyProc(AValue: string); override; 
  end;

Les méthodes virtuelles sont particulièrement intéressantes lorsque vous ignorez quels objets vont être précisément activés à l'exécution.

Mis à jour le 18 août 2016 gvasseur58

Pour une mise en œuvre du polymorphisme avec une méthode virtuelle, voir ici.

Le mot réservé inherited permet d’hériter du comportement d'une méthode d’un parent tout en autorisant des compléments.

Dans l'exemple suivant, si TChien descend de TAnimal, l'appel à la méthode Manger de TChien affichera 'Je mange... mais principalement de la viande !' :

Code pascal : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
procedure TAnimal.Manger; 
begin 
  writeln('Je mange.'); 
end; 
  
procedure TChien.Manger; 
begin 
  inherited Manger; // on hérite de la méthode du parent 
  writeln('.. mais principalement de la viande !'); 
end;

Mis à jour le 18 août 2016 gvasseur58

La directive override définit une méthode de classe comme surchargeant la même méthode nommée dans une classe parente. L'ancienne méthode est toujours accessible grâce à inherited.

Code pascal : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
  
type 
  TMyClass = class 
    procedure MyProc; virtual; 
  end; 
  
  TMySubClass = class(TMyClass) 
    procedure MyProc; override; 
  end; 
  
[...] 
  
implementation 
  
  procedure TMyClass.MyProc; 
  begin 
    Width := 50; 
    Height := 60; 
  end; 
  
  procedure TMySubClass.MyProc; 
  begin 
    inherited; // on reprend ce que fait la méthode de l'ancêtre 
    Top := 100; // nouvelle valeur 
  end;

N.B. : la directive override ne s'applique qu'à des méthodes virtuelles.

Mis à jour le 19 août 2016 gvasseur58

Avec Free Pascal, une méthode marquée dynamic n'est rien d'autre qu'une méthode virtuelle. dynamic est par conséquent équivalent à virtual.

La directive dynamic existe pour la compatibilité avec Delphi.

Mis à jour le 19 août 2016 gvasseur58

La directive reintroduce signifie au compilateur que l'écrasement de la méthode virtuelle de l'ancêtre est volontaire.
Redéfinir complètement une méthode virtuelle par une méthode statique provoque un avertissement du compilateur : faire suivre la redéfinition de la méthode virtuelle par la directive reintroduce évite cet avertissement.

Code pascal : Sélectionner tout
1
2
3
4
5
6
7
8
// méthode du parent 
TMyClass = class 
  procedure MyProc; // la méthode est virtuelle 
end; 
  
// méthode du descendant 
TMySubClass = class(TMyClass) 
procedure MyProc; reintroduce; // la méthode virtuelle est écrasée

N.B. : Cette directive est utile pour surcharger une méthode dont il faut modifier les paramètres d'appel, par exemple pour un constructeur.

Mis à jour le 19 août 2016 gvasseur58

Une méthode abstraite est un squelette de méthode déclarée dans une classe, mais non implémentée. Ce sont les descendants de la classe où la déclaration a eu lieu qui l'implémenteront en temps voulu.

Code pascal : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
type 
  TMyClass = class 
  public 
    procedure DoSomething;  virtual; abstract; 
 end; 
  
  TMySubClass = class(TMyClass) 
  public 
    procedure DoSomething; override; 
  end;

N.B. : Une méthode abstraite doit toujours être déclarée virtuelle. Faute d’implémentation, on prendra bien garde de ne pas faire appel à ces méthodes et de ne pas utiliser inherited lors d’un héritage direct.

Mis à jour le 21 août 2016 gvasseur58

L'intérêt de la directive abstract est d'unifier les déclarations et le comportement des classes tout en bénéficiant totalement du polymorphisme si nécessaire.

Par exemple, les descendants de TStrings procéderont à l'implémentation de ses méthodes abstraites tandis qu'en tant qu’ancêtre, TStrings sera d’une grande polyvalence puisque n'importe quel descendant pourra prendre sa forme.

Comparez :

Code pascal : Sélectionner tout
1
2
3
4
5
6
7
procedure Afficher(Sts: TStringList); 
var 
  LItem: string; // variable locale pour récupérer les chaînes une à une 
begin 
  for LItem in Sts do // on balaie la liste 
    writeln(LItem); // et on affiche l’élément en cours 
end;

Et :

Code pascal : Sélectionner tout
1
2
3
4
5
6
7
procedure Afficher(Sts: TStrings); // <= seul changement 
var 
  LItem: string; 
begin 
  for LItem in Sts do 
    writeln(LItem); 
end;

La première procédure n'acceptera pour paramètre que les objets de type TStringList. La seconde acceptera tous les descendants de TStrings, y compris TStringList, se montrant par conséquent bien plus polyvalente.

Mis à jour le 21 août 2016 gvasseur58

Avec les méthodes de classe, vous ne vous intéresserez plus à l’instanciation, mais à la manipulation directe de la classe. Dans d’autres domaines, on parlerait de métadonnées. Il est par conséquent inutile d’instancier une classe pour accéder à ces méthodes particulières, même si cela reste possible.

La déclaration d’une méthode de classe se fait en plaçant le mot-clé class avant de préciser s’il s’agit d’une procédure ou d’une fonction.

Par exemple, voici comment déclarer une fonction qui renverrait le copyright associé à un programme :

Code pascal : Sélectionner tout
1
2
3
4
5
6
  
type 
  TMyClass = class 
  public 
     class function Copyright: string; 
  end;

L'implémentation doit reprendre class et pourrait ressembler à :

Code pascal : Sélectionner tout
1
2
3
4
class function TMyClass.Copyright: string; 
begin 
  Result := 'www.developpez.com 2016'; 
end;

Pour qu'une étiquette affiche le texte du copyright, l'appel prendrait alors la forme :

Code pascal : Sélectionner tout
MyLabel.Caption := TMyClass.Copyright;

L’important est de remarquer que l’appel a été effectué sans instancier TMyClass.

Mis à jour le 24 août 2016 gvasseur58

En ajoutant la directive static à la fin de la déclaration d’une méthode de classe, vous obtenez une méthode statique de classe.

Une méthode statique de classe ne connaît ni le paramètre Self ni la virtualité. En fait, une méthode de ce type se comporte en tout point comme procédure ou fonction ordinaires.

Code pascal : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
type 
  
  TMyClass = class 
    private 
      class var fMyValue: string; 
    protected 
      class procedure SetMyValue(const AValue: string); static; 
      class function GetMyValue: string; static; 
    public 
      class property MyValue: string read GetMyValue write SetMyValue; 
  end;

L'utilisation d'une méthode statique de classe au lieu d'une routine globale permet de la nommer avec le préfixe de la classe et non celui de l’unité où elle a été définie : c'est là son principal usage. Grâce à ce changement d'espace de nommage, la lisibilité du code en est meilleure et les conflits de noms en sont d'autant limités.

Mis à jour le 24 août 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 -