Difference between revisions of "Object Oriented Programming with Free Pascal and Lazarus/fr"

From Free Pascal wiki
Jump to navigationJump to search
(Mise à jour)
m (Fixed syntax highlighting)
 
(6 intermediate revisions by 4 users not shown)
Line 1: Line 1:
{{Object_Oriented_Programming_with_FreePascal_and_Lazarus}}
+
{{Object Oriented Programming with Free Pascal and Lazarus}}
  
 
==Introduction==
 
==Introduction==
Line 95: Line 95:
 
----
 
----
  
If a Button control is placed on the Form (type TButton), it will have its own series of properties, which can be examined in the Object Inspector window.  
+
Si un contrôle "Bouton" est placé sur cette fiche (type TButton), il aura ses propres séries de propriétés, qui pourront être examinées dans la fenêtre de l'inspecteur d'objets.  
  
Several of the properties have names similar to those for the Form; this is because many properties are '''Inherited''' from some common Ancestor class, which lays out how properties are to be defined and handled by the descendant classes.  
+
Plusieurs propriétés ont des noms similaires à celles de la fiche. C'est parcequ'elles sont héritées d'ancètres communs qui indiquent comment les propriétés doivent être définies et manipulées par les classes descendantes.
  
 
As well as properties, the Object Inspector offers a tab called '''Events''', which gives access to Event Handlers which are methods instructing the application how to deal with things such as a mouse click on a button (OnClick) or some change in the position, size or other properties (OnChange).
 
As well as properties, the Object Inspector offers a tab called '''Events''', which gives access to Event Handlers which are methods instructing the application how to deal with things such as a mouse click on a button (OnClick) or some change in the position, size or other properties (OnChange).
Line 117: Line 117:
 
For example, an object could contain an array of real values, together with a Method for calculating the average.
 
For example, an object could contain an array of real values, together with a Method for calculating the average.
  
Type
+
<syntaxhighlight lang=pascal>
  Average = Object
+
Type
    NumVal: Integer;
+
  Average = Object
    Values: Array [1..200] of Real;
+
    NumVal: Integer;
    Function Mean: Real; { calculates the average value of the array }
+
    Values: Array [1..200] of Real;
  End;
+
    Function Mean: Real; { calculates the average value of the array }
 +
  End;
 +
</syntaxhighlight>
  
 
Objects can ”inherit” fields and methods from ”parent” objects. This means that these fields and methods can be used as if they were included in the objects declared as a ”child” object.
 
Objects can ”inherit” fields and methods from ”parent” objects. This means that these fields and methods can be used as if they were included in the objects declared as a ”child” object.
Line 135: Line 137:
  
 
Here is a simple example of a typical Class declaration:
 
Here is a simple example of a typical Class declaration:
<delphi>{-------------------------------------------}
+
<syntaxhighlight lang=pascal>{-------------------------------------------}
 
{ Example of Class declaration from the LCL }
 
{ Example of Class declaration from the LCL }
 
{-------------------------------------------}
 
{-------------------------------------------}
Line 170: Line 172:
 
     property Style default psSolid;
 
     property Style default psSolid;
 
     property Width default 1;
 
     property Width default 1;
   end;</delphi>
+
   end;</syntaxhighlight>
  
  
Line 201: Line 203:
  
 
====Examples====
 
====Examples====
<delphi>
+
<syntaxhighlight lang=pascal>
 
   TFooClass = class
 
   TFooClass = class
 
   private
 
   private
Line 208: Line 210:
 
     property IntProp: Integer read FIntProp write FIntProp;
 
     property IntProp: Integer read FIntProp write FIntProp;
 
   end;
 
   end;
</delphi>
+
</syntaxhighlight>
  
<delphi>
+
<syntaxhighlight lang=pascal>
 
   TFooClass = class   
 
   TFooClass = class   
 
   private
 
   private
Line 219: Line 221:
 
     property ListProp[AIndex: Integer]: String read GetListProp write SetListProp;  
 
     property ListProp[AIndex: Integer]: String read GetListProp write SetListProp;  
 
   end;
 
   end;
</delphi>
+
</syntaxhighlight>
  
<delphi>
+
<syntaxhighlight lang=pascal>
 
   TFooClass = class
 
   TFooClass = class
 
   private
 
   private
Line 236: Line 238:
 
     // property Value: Integer index ord(seSomeEnum) read SomeFunction write SomeProcedure;
 
     // property Value: Integer index ord(seSomeEnum) read SomeFunction write SomeProcedure;
 
   end;
 
   end;
</delphi>
+
</syntaxhighlight>
  
 
== Extensions du langage Free Pascal ==
 
== Extensions du langage Free Pascal ==

Latest revision as of 12:37, 21 February 2020

English (en) español (es) français (fr) magyar (hu) italiano (it) македонски (mk) русский (ru) 中文(中国大陆)‎ (zh_CN) 中文(台灣)‎ (zh_TW)

Introduction

Il y a beaucoup d'excellents tutoriels sur Pascal, mais ce tutoriel-ci tente d'amener le débutant plus loin, dans (la programmation orienté objet) Object-Oriented Programming, qui est une extension de la norme Pascal standard, offert par Turbo-pascal, Delphi et FreePascal/Lazarus.

Un objet Object est une extension de la structure record du Pascal record

La programmation Pascal standard en mode texte est bien adaptée à la création d'applications qui, comme les applications Unix, font une chose, et la font très bien. Un programme peut réaliser une tâche très compliquée, et offrir à l'utilisateur plusieurs options accessibles par menus ; mais, essentiellement, cela se résume à obéir à des commandes tapées au clavier par l'utilisateur et à afficher les réponses sur le terminal ou l'imprimante.

Pour pouvoir founir une Interface Utilisateur Graphique ( Graphical User Interface (GUI)), il est habituel d'invoquer une méthode de Programmation Orientée Objet ou une autre (en utilisant souvent C, ou l'une de ses variantes, ou Visual Basic, ou l'une des variantes OO de Pascal telle que FreePascal avec ou sans Lazarus).

Dans un(e) GUI, l'utilisateur est confronté à un écran présentant une grande quantité d'images, disposées de façon structurée, et consistant en un ensemble d'outils ou de Widgets qui sont associés à diverses actions telles que :

  • sélection depuis un menu ;
  • ouverture ou sauvegarde d'un fichier ;
  • connection à Internet ;
  • réalisation de calculs numériques ;
  • etc.

L'utilisateur doit alors déplacer une souris ou un autre périphérique de pointage et de sélection, pour sélectionner à l'écran les actions à réaliser en réponse à un clic de souris ou à une pression de touche sur le clavier.

Alors que les systèmes prenant en charge une interface utilisateur graphique complexe peuvent être écrits en Pascal, ou quasiment n'importe quel autre langage de programmation, il est bien plus aisé d'utiliser un système orienté objet, dans lequel les propriétés, les procédures et les fonctions relatives à l'utilisation de chaque objet graphique présent à l'écran peuvent être rassemblées dans une structure commune.

Objets - analogie avec le monde réel

Considérons l'analogie avec un prélèvement sanguin dans un hôpital ou le cabinet d'un médecin.

Prélèvement sanguin

Le résultat physique du prélèvement est certainement un objet ; des informations lui sont associées, ainsi que des documents et plusieurs autres objets physiques.

  • Tube à essai, d'un type déterminé par le test que le médecin souhaite faire ;
  • Règle locale (ou méthode, procédure opérationnelle standard) pour guider l'infirmière ou le technicien chargé du prélèvement :
    • quel type de tube utiliser ;
    • comment traiter le prélèvement ;
    • comment le conserver avant son transfert au laboratoire ;
  • Etiquette sur le tube avec :
    • l'identifiant du prélèvement ;
    • le nom et la date de naissance du patient ;
    • la date et l'heure de la prise de sang ;
    • les tests demandés ;
  • Formulaire de demande qui accompagne le prélèvement jusqu'au laboratoire, indiquant :
    • l'ID du prélèvement ;
    • l'ID de médecin requérant ;
    • quels tests le médecin demande et
    • donnant de plus d'information sur le patient ;
    • le diagnostic que l'on souhaite confirmer.

Une copie du formulaire de demande est placée dans le dossier du patient, pour rappeler au médecin de vérifier la réception des résultats en temps voulu.

  • Au laboratoire - méthodes locales pour établir :
    • comment le prélèvement doit être analysé ;
    • quelles machines utiliser ;
    • de quelle façon calibrer et utiliser les machines ;
    • comment formater et enregistrer les résultats, et
    • comment les transmettre au médecin.

Les résultats sont des données que le médecin exploite pour conforter le diagnostic, et une copie en est classée dans le dossier du patient.

Le produit physique du prélèvement peut être conservé pour référence, confirmation ou tests complémentaires, ou bien jeté ou incinéré ; il y aura une méthode décrivant l'action à mener.

There is no need for a physician to spell out all the details and instructions every time a sample is collected; indeed, he may have very little knowledge of how the sample is processed in the lab. The details of the various processes are inherited from previous sample collections and analyses - there will be a generic plan for the whole sequence, and together we could think of the blood sample, all its documents and data, and the underlying methods, as a complex object.

In the physician's mind, the blood sample is seen as almost the same entity as its results, and to the nurses and technicians the sample, the tube, the label and the storage conditions again form a single entity.

Un autre exemple - L'automobile

Si vous n'aimez pas le sang, le même raisonnement peut être appliqué à une voiture déposée dans un garage pour une réparation. Il pourrait s'agir :

  • Du véhicule physique
  • Des documents du propriétaire: le permis de conduire, carte grises (les plaques d'immatriculation), les assurances, les factures d'entretien, réparations, etc
  • l'histoirique de consommation de carburant
  • les conducteurs autorisés à utiliser le véhicule, avec les numéros des permis de conduire
  • le service des documents détenus par le garage
  • des méthodes ou procédures à suivre pour les contrôles de routine et de maintenance
  • des méthodes à suivre pour les réparations exceptionnelles, etc ...
  • des factures pour le client

Exemple de programmation

Assez de ces pré-occupation sur le monde réel! Passons à l'objectif principal: la programmation en FreePascal.

Considérons la création d'une simple Fiche (Form) avec quelques contrôles pour une application en FreePascal/Lazarus.

ObjectInspector-TForm.png
BlankForm.png

Au lancement de l'IDE Lazarus, le programmeur fait face à un modèle de Fiche vierge sur lequel il est invité à placer des contrôles ou objets divers.

Remarquez que cette Fiche préfabriquée est déjà un Objet, avec ses propres propriétés telles que la position (Top et Left), la taille (Height et Width), la couleur, la police par défaut pour l'ajout de texte, etc., ...


Si un contrôle "Bouton" est placé sur cette fiche (type TButton), il aura ses propres séries de propriétés, qui pourront être examinées dans la fenêtre de l'inspecteur d'objets.

Plusieurs propriétés ont des noms similaires à celles de la fiche. C'est parcequ'elles sont héritées d'ancètres communs qui indiquent comment les propriétés doivent être définies et manipulées par les classes descendantes.

As well as properties, the Object Inspector offers a tab called Events, which gives access to Event Handlers which are methods instructing the application how to deal with things such as a mouse click on a button (OnClick) or some change in the position, size or other properties (OnChange).

The physical image of the Button on the Form, together with all its properties and Event Handler methods, should be regarded as a single entity or Object in Pascal.

ObjectInspector-TButton.png
FormWithButton.png
Source FormWithButton1.png

Object-Oriented Extensions to standard Pascal

The Pascal record structure is extended by defining an

Object

An Object is a special kind of record. The record contains all the fields that are declared in the object's definition (just like a conventional record), but now procedures and functions can be declared as if they were part of the record and are held as pointers to the methods associated with the object's type.

For example, an object could contain an array of real values, together with a Method for calculating the average.

Type
  Average = Object
    NumVal: Integer;
    Values: Array [1..200] of Real;
    Function Mean: Real; { calculates the average value of the array }
  End;

Objects can ”inherit” fields and methods from ”parent” objects. This means that these fields and methods can be used as if they were included in the objects declared as a ”child” object.

Furthermore, a concept of visibility is introduced: fields, procedures and functions can be declared as public, protected or private. By default, fields and methods are public, and can be exported outside the current unit. Protected fields or methods are available only to objects descended from the current ancestor object. Fields or methods that are declared private are only accessible in the current unit: their scope is limited to the implementation of the current unit.

Class

Objects are not used very often by themselves in Free Pascal and Lazarus; instead, Classes are used very widely. A Class is defined in almost the same way as an Object, but is a pointer to an Object rather than the Object itself. Technically, this means that the Class is allocated on the Heap of a program, whereas the Object is allocated on the Stack.

Here is a simple example of a typical Class declaration:

{-------------------------------------------}
{ Example of Class declaration from the LCL }
{-------------------------------------------}
  TPen = class(TFPCustomPen)
  private
    FColor: TColor;
    FPenHandleCached: boolean;
    FReference: TWSPenReference;
    procedure FreeReference;
    function GetHandle: HPEN;
    function GetReference: TWSPenReference;
    procedure ReferenceNeeded;
    procedure SetHandle(const Value: HPEN);
  protected
    procedure DoAllocateResources; override;
    procedure DoDeAllocateResources; override;
    procedure DoCopyProps(From: TFPCanvasHelper); override;
    procedure SetColor
         (const NewColor: TColor; const NewFPColor: TFPColor); virtual;
    procedure SetFPColor(const AValue: TFPColor); override;
    procedure SetColor(Value: TColor);
    procedure SetMode(Value: TPenMode); override;
    procedure SetStyle(Value: TPenStyle); override;
    procedure SetWidth(value: Integer); override;
  public
    constructor Create; override;
    destructor Destroy; override;
    procedure Assign(Source: TPersistent); override;
    property Handle: HPEN read GetHandle write SetHandle; deprecated;
    property Reference: TWSPenReference read GetReference;
  published
    property Color: TColor read FColor write SetColor default clBlack;
    property Mode default pmCopy;
    property Style default psSolid;
    property Width default 1;
  end;


Note that this class is defined as an instance of another parent or ancestor class (TFPCustomPen) from which it inherits all its properties and methods. It has some fields of its own, grouped under

  • private - this means that items defined here are only available or visible to other classes or procedures/function defined within the same program unit (this example is from Graphics, so any of the other classes such as TBitMap, TPicture etc in the same unit can use them). They are essentially local variables (eg FColor, FPenHandleCached) or locally used methods (GetHandle, SetHandle) but can be used or referred to in items declared in the protected or public sections.
  • protected - this means that items defined here are only available or visible to classes that are descended from this ancestor class, and inherit its properties or methods
  • public - this means that items defined here are available to any programming unit that includes the current unit in its Uses clause
  • published - is the same as a public section, but the compiler also generates type information that is needed for automatic streaming of these classes. Often the list of published items appear in the Object Inspector of Lazarus; if there is no published list, all the public fields usually appear in the Object Inspector.

Methods

A method is just like a standard procedure or function, but can have some additional directives.

Some of the methods defined above are labelled with the directive virtual; others are labelled with the override directive.

  • virtual means that the type or actual instance of a method is not known at compile-time, but is selected at run-time depending on what sub-program actually calls the method. It could be considered a place-holder in the definition of the class.
  • override means that at run-time the locally given definition can take the place of a definition inherited from an ancestor class, particularly if it was virtual. If you particularly want to use the method defined in the ancestor class, it is sometimes necessary to call it specifically with the inherited clause.

Methods with no virtual or override directive are static methods (the usual kind in Pascal). Those with a virtual or override directive are dynamic.

Special instances of methods are:

  • create - a constructor for a class, which takes care of allocating memory, collecting together all the information needed and configuring/initializing the various properties.
  • destroy - a destructor for a class, which removes all the parts of the class from the system in an orderly and logical way, and returns all its resources for the system to re-use.

Properties

Properties are just like ordinary fields in a conventional Pascal record, but they can have read and/or write specifiers.

  • read specifier is a field, or a function that returns a result of the correct type for the property. In the example above, the property Color has a read specifier FColor, which is a local variable containing the value to be used. If a property has a read but no write specifier, it is read-only.
  • write specifier is a field, or a procedure that will store the value of the property in a specific location. In the example above, Color has a write specifier SetColor that is a procedure (defined in the protected section) for writing the color value to some specified location. If a property has a write but no read specifier, it is write-only.
  • default - note that it is possible to set a default value for a property. For example, Color here is given the default value clBlack, or black, at the time of creation. It could subsequently be given a different value, by a programming assignment statement, or in the Object Inspector.
  • index specifier is an integer that the read or write methods, shared between properties, can use to identify which property is desired. Note that if index is used the read or write specifiers must be a function or a procedure respectively and cannot be a normal field/variable.

Examples

  TFooClass = class
  private
    FIntProp: Integer;
  public
    property IntProp: Integer read FIntProp write FIntProp;
  end;
  TFooClass = class  
  private
    function GetListProp(AIndex: Integer): String;
    property SetListProp(AIndex: Integer; AValue: String);
  public
    // this type of property may not be in the published section of a class
    property ListProp[AIndex: Integer]: String read GetListProp write SetListProp; 
  end;
  TFooClass = class
  private
   function GetValue(const AIndex: Integer): Integer;
   procedure SetValue(const AIndex: Integer; AValue: Integer);
  public
    // note that the read and write methods are shared
    property Value1: Integer index 1 read GetValue write SetValue;
    property Value2: Integer index 2 read GetValue write SetValue;
    property Value3: Integer index 3 read GetValue write SetValue;
    property Value4: Integer index 4 read GetValue write SetValue;
    // index may be a const or a number or you can even use an enumerated type
    // for example:
    // property Value: Integer index ord(seSomeEnum) read SomeFunction write SomeProcedure;
  end;

Extensions du langage Free Pascal

FPC inclut plusieurs extensions dans son langage par rapport à la syntaxe Pascal "standard" pour supporter la Programmation Orientée Objet (POO).

Ces extensions sont décrites dans les chapitres indiqués du guide de référence du langage FPC: http://www.freepascal.org/docs.var. Des liens vers les pages de tutoriel pour chaque concept sont de même inclus ci-dessus. Le Guide de référence du langage comprend des diagrammes sur la syntaxe et d'autres détails ne figurant pas dans ce tutoriel d'introduction. Parmi les quatre caractéristiques du langage mentionnées ci-dessus, Objets et Classes forment la base de la Programmation Orientée Objet (POO) dans FPC et Lazarus. Pour les nouveaux avec la POO, le paragraphe Objets comprend plus d'introduction sur les concepts et le paragraphe Classes minimise la répétition en mettant l'accent sur les similitudes et les différences avec la syntaxe Objets. En général, l'implémentation Classes semble être plus largement utilisée, y compris par les développeurs Delphi et Lazarus. Souvent, le mot "objets" est utilisé pour se référer à ce qui est en fait une "classe" dans le dialecte Classes de la POO dans FPC. Ces documents seront libellés de telle manière à réduire au minimum toute confusion de terminologie, mais en dehors de ce document, souvent, le terme "objet" se réfère à des objets créés à partir d'une Classe. En fait, la bibliothèque d'exécution de FPC (RTL) comprend une bibliothèque de classes avec une classe de base appelée TObject.

Les utilisateurs familiers avec l'ancienne implémentation de la POO de Turbo Pascal peuvent initialement souhaitez sauter la section sur les classes puisque l'implémentation des objets est basée sur l'ancien dialecte de Turbo Pascal. La section sur les Classes devrait être familière pour les utilisateurs de Delphi car elle est fondée sur la syntaxe Delphi. Soyez conscient que certaines des descriptions dans la section Classes peuvent se rapporter à des concepts de la section Objets. Pour les développeurs Macintosh familiarisés avec les différents dialectes en pascal objet d'Apple, THINK et MPW, ni le dialecte des classes ni celui des objets de FPC ne fournissent une voie de migration directe. À partir de Mars 2009, il y a des discussions sur la Liste de diffusion du Pascal pour Mac dans le but de potentiellement fournir quelque soutien du compilateur (nouvelle syntaxe) pour accéder au framework en langage objet C/Cocoa d'Apple.

Concepts généraux du Pascal orienté objet

La POO propose différentes façons de gérer et d'encapsuler les données et de gérer les flux de programmes comparé à d'autres caractéristiques et constructions de langage de programmation. La POO souvent, se prête à la modélisation de certaines applications tels que les interfaces Graphiques utilisateur(GUI's) et les systèmes physiques dans une manière de penser plus naturelle. Cependant la POO n'est pas approprié pour toutes les applications. Le contrôle de programme n'est pas aussi explicite que les plus élémentaires construction de procédure en Pascal. Pour obtenir le plus grand bénéfice de la POO, la compréhension de grandes bibliothèques de classes est souvent nécessaire ce qui peut entraîner une rude voie d'apprentissage. le maintien d'un grand code d'application avec la POO a ses avantages et ses inconvénients comparativement à maintenir du code procédural strict. Il existe de nombreuses sources d'apprentissage pour l'analyse, la conception et les techniques de programmation en POO qui sont au-delà de la portée de ce guide.

Il existe de nombreux langages de programmation qui incorporent des fonctionnalités de la POO comme des extensions ou bien comme base de leur langue. En tant que tel, il y a beaucoup de termes différents pour décrire les concepts de POO. Même dans le langage FPC, certains des termes de recoupent. En général, la POO consiste habituellement en la notion de programmation objet(ou unité d'information) qui associe explicitement et encapsule un ensemble de données et de procédures qui agissent sur les données. Ces données sont généralement persistantes au cours de l'exécution du programme mais avec des mécanismes visant à réduire certains des problèmes inhérents à la déclaration des variables globales. En outre, les langages de POO permettent à des objets une modification progressive et/ou une extension basée sur des objets défini précédemment. Cette fonctionnalité est généralement appelé par les termes héritage et polymorphisme. Beaucoup de langages de POO utilisent les termes méthode ou message se référant à des procédures qui appartiennent à un objet. Une grande partie de la puissance de la POO est réalisée par (au moment de l'exécution) la liaison dynamique tardive des méthodes plutôt que la liaison à la compilation. Cette liaison dynamique des méthodes est similaire à l'utilisation de variables procédurales et de paramètres procéduraux mais avec une plus grande cohésion syntaxique, l'encapsulation des données auxquelles il est lié et aussi l'héritage du comportement des méthodes précédemment définies. Les pages wiki suivantes fournissent un point de départ pour en découvrir plus au sujet de l'analyse, la conception et la programmation d'une manière orientée objet.

Information complémentaire

Ceci n'a fait qu'effleurer le sujet. Pour de plus amples détails, il est fortement conseillé au lecteur de se reporter aux manuels FreePascal, et en particulier aux chapitres 5 (Objets) et 6 (Classes).

Voir aussi

Liens externes