Compréhension : POO & Interfaces
Publié : jeu. 29/sept./2005 23:09
Voici une méthode "simple" pour faire des de la Programmation Orientée Objet dans PB.
Le but n'étant pas d'expliquer les classes, héritages et autres surcharges mais bien de montrer un code qui fonctionne et "simple".
Pour approfondir la chose j'ai trouvé un tuto très complet et en Français sur le sujet fait par Dräc:
http://drac.site.chez.tiscali.fr/Tutori ... ls.htm#POO
Le principe de cet exemple est de faire un "composant" qui va réaliser une addition (c'est con mais c'est simple).
Les interfaces étant ce qu'elles sont il faut savoir qu'il n'y a que des procédures qui seront "visibles" pendant l'utilisation de l'objet.
Afin d'avoir des "propriétés" liées à l'objet on détournera les variables "internes" de l'objet en créant des procédures (SetX, GetX...).
Ce subterfuge va permettre d'avoir plusieurs objets avec des propriétés différentes au lieu d'une simple liste de fonctions.
Je rappelle que le but n'est pas d'expliquer de long en large l'utilisation des structures mais de montrer que la création d'un objet est à la portée de tous.
Pour créer une librairie avec un objet dedans il faudra faire quelques modifications:
- Changer Procedure par ProcedureDLL
- Mettre dans une procédure "_Init" (voir doc Tailbite) l'assignation des adresses (ce qui suit le Global).
- Laisser le Global, l'interface et les structures comme elles sont.
Le but n'étant pas d'expliquer les classes, héritages et autres surcharges mais bien de montrer un code qui fonctionne et "simple".
Pour approfondir la chose j'ai trouvé un tuto très complet et en Français sur le sujet fait par Dräc:
http://drac.site.chez.tiscali.fr/Tutori ... ls.htm#POO
Le principe de cet exemple est de faire un "composant" qui va réaliser une addition (c'est con mais c'est simple).
Les interfaces étant ce qu'elles sont il faut savoir qu'il n'y a que des procédures qui seront "visibles" pendant l'utilisation de l'objet.
Afin d'avoir des "propriétés" liées à l'objet on détournera les variables "internes" de l'objet en créant des procédures (SetX, GetX...).
Ce subterfuge va permettre d'avoir plusieurs objets avec des propriétés différentes au lieu d'une simple liste de fonctions.
Code : Tout sélectionner
; Déclaration des fonctions de notre objet dans une Interface.
; Lors de l'utilisation de l'objet le programmeur ne verra que ça
; et donc il faudra implémenter des fonctions pour modifier
; et récupérer les "propriétés" de notre objet.
Interface Math_Object
SetX(x)
GetX.l() ;<-- cette procédure retourne une valeur donc on indique le type
SetY(y)
Add.l()
Free()
EndInterface
; Déclaration d'une structure pour y stocker les adresses des procédures.
; Il faudra une déclaration par procédure utilisée dans l'objet
; et elles seront toutes de type Long (pour stocker l'adresse).
; Pour des raisons obscures il faut impérativement garder EXACTEMENT
; le même ordre que pour l'interface.
Structure Math_Functions_Addresses
SetX.l
GetX.l
SetY.l
Add.l
Free.l
EndStructure
; Déclaration de la structure "interne" de l'objet, càd la structure
; des procédures ainsi que les variables (les propriétés de l'objet).
Structure Math_Internal_Structure
*Virtual.Functions_Addresses
x.l ;<-- variable interne, peut être de n'importe quel type
y.l
EndStructure
; Nos procédures
; Le paramètre *Object permet de faire référence à l'objet en lui même
; et est obligatoire dans le cas où on veut accéder à ses "propriétés".
Procedure SetX(*Object.Math_Internal_Structure, x)
*Object\x = x ;<-- ici on change la valeur de la propriété x.
EndProcedure
Procedure.l GetX(*Object.Math_Internal_Structure)
ProcedureReturn *Object\x
EndProcedure
Procedure SetY(*Object.Math_Internal_Structure, y)
*Object\y = y
EndProcedure
Procedure.l Add(*Object.Math_Internal_Structure)
ProcedureReturn *Object\x + *Object\y
EndProcedure
; Ceci est le "destructeur", càd qu'il va permettre de libérer la mémoire
; et donc de détruire l'objet.
; C'est un simple FreeMemory mais il peut être utile d'effectuer diverses
; tâches comme fermer un fichier ou une connexion réseau.
Procedure Free(*Object.Math_Internal_Structure)
FreeMemory(*Object)
EndProcedure
; Ici on va déclarer une variable globale qui va contenir les adresses
; de nos procédures.
; Il est important de ne pas modifier ces valeurs à l'exécution.
Global Math_Global.Math_Functions_Addresses
Math_Global\SetX = @SetX()
Math_Global\GetX = @GetX()
Math_Global\SetY = @SetY()
Math_Global\Add = @Add()
Math_Global\Free = @Free()
; Déclaration du "constructeur". Contrairement au destructeur il va
; allouer l'espace mémoire pour l'objet.
; Si cette procédure est appellée 10 fois il faudra détruire les
; 10 objets créés. La valeur retournée est le pointeur de cet objet.
; Remarque: c'est la seule procédure qui ne doit pas se trouver dans
; l'interface vu que l'objet n'existe pas encore.
Procedure.l NewMath_Object()
*new.Math_Internal_Structure = AllocateMemory(SizeOf(Math_Internal_Structure))
*new\Virtual = Math_Global
ProcedureReturn *new
EndProcedure
;-------------------
;Testons la chose :)
;-------------------
MonMath.Math_Object = NewMath_Object() ;<-- création de l'objet
; Utilisation des procédures de l'objet
MonMath\SetX(5)
MonMath\SetY(2)
Debug MonMath\Add()
Debug MonMath\GetX()
; On oublie pas de détruire l'objet
MonMath\Free()
Pour créer une librairie avec un objet dedans il faudra faire quelques modifications:
- Changer Procedure par ProcedureDLL
- Mettre dans une procédure "_Init" (voir doc Tailbite) l'assignation des adresses (ce qui suit le Global).
- Laisser le Global, l'interface et les structures comme elles sont.