[Basic] Programmation orientée objet

Venez découvrir tous les tutoriels, modèles et autres foires aux questions afin de maîtriser rapidement votre suite bureautique favorite.

Modérateur : Vilains modOOs

Règles du forum
Aucune question dans cette section !
Cette section est faite pour présenter les tutoriels. Si vous avez une question sur l'installation, le fonctionnement ou l'utilisation, vous devez poster dans la section du module où se produit le problème.
JPL
Membre lOOyal
Membre lOOyal
Messages : 33
Inscription : 17 mars 2012 11:16
Contact :

[Basic] Programmation orientée objet

Message par JPL »

Un secret bien gardé.

La définition en BASIC de modules de classes est parfaitement possible comme cela l'est en Visual Basic.
Le niveau de sophistication de ces modules et leur syntaxe est comparable à ce qu'ils sont en VB6.
La suite de ce sujet en illustre les possibilités par quelques exemples.

Comment procéder ?

Définition d'une classe :

Code : Tout sélectionner

Option Compatible
Option ClassModule

Option Explicit

REM -----------------------------------------------------------------------------------------------------------------------
REM --- Internal Variables																									---
REM -----------------------------------------------------------------------------------------------------------------------

Private _X		As Double
Private _Y		As Double

REM -----------------------------------------------------------------------------------------------------------------------
REM --- CONSTRUCTORS / DESTRUCTORS						        														---
REM -----------------------------------------------------------------------------------------------------------------------
Private Sub Class_Initialize()
'	Default point = Origin of axis
	_X = 0
	_Y = 0
End Sub		'	Constructor

REM -----------------------------------------------------------------------------------------------------------------------
Private Sub Class_Terminate()
	_X = - 4.94065645841247E-324		'	Most negative value allowed for Double variables
	_Y = - 4.94065645841247E-324
end sub

REM -----------------------------------------------------------------------------------------------------------------------
REM --- CLASS GET/LET/SET PROPERTIES					        														---
REM -----------------------------------------------------------------------------------------------------------------------

Public Property Get X As Double
	X = _X
End Property

Public Property Let X(ByVal pValue As Double)
	_X = pValue
End property

REM -----------------------------------------------------------------------------------------------------------------------
Public Property Get Y As Double
	Y = _Y
End Property

Public Property Let Y(ByVal pValue As Double)
	_Y = pValue
End property

REM -----------------------------------------------------------------------------------------------------------------------
Public Property Get Dummy As Variant
	Dummy = Null
End Property

REM -----------------------------------------------------------------------------------------------------------------------
REM --- CLASS METHODS	 								        														---
REM -----------------------------------------------------------------------------------------------------------------------

Public Sub Move(ByVal pX As Double, ByVal pY As Double)
	_X = _X + pX
	_Y = _Y + pY
End Sub
Si ce code est saisi dans un module nommé « Point » le nom de la classe sera également « Point ».

Les lignes « Option Compatible » et « Option ClassModule » en tête du module sont celles qui déterminent la caractéristique du module, à savoir qu'il s'agit d'un module de classe. Elles doivent se trouver dans l'ordre indiqué. Dans le cas contraire, la source ne passera pas la compilation.

Un module de classe contient un certain nombre de Variables Internes. Elles sont regroupées en-dehors des function/sub et reçoivent généralement l'attribut « Private ». Il signifie que la variable interne ne peut être utilisée que dans le module même, contrairement à la valeur « Public ». A noter que cet attribut est ignoré en Basic. Les variables concernées peuvent être de tout type, y compris une autre classe. Un exemple sera donné plus bas. Une variable interne peut également contenir un objet UNO.

Les Sub « Class_Initialize » et « Class_Terminate » sont resp. Les constructeur et destructeur de la classe. Elles sont exécutées, pour la première, avant la première utilisation d'une instance de classe, pour la seconde, lors de sa suppression (voir plus bas).

Les propriétés sont déterminées par les définitions « Property Get », « Property Let » et « Property Set ». « Get » fournit la valeur de la propriété, « Let » correspond à une assignation classique, « Set » permet la transmission d'objets ou de structures complexes. Notez que la valeur retournée par « Property Get » ainsi que l'argument de « Property Let » doivent être de TYPE IDENTIQUE.
A noter que l'instruction « Exit » s'enrichit d'une option « Exit Property ».

Les méthodes sont des Sub ou des Function. Une Sub exécute une action quelconque et représente le cas le plus fréquent d'une méthode.

Utilisation de la classe « Point »:

La déclaration d'une instance de classe se fait par l'instruction « Dim ». La variable associée sera déclarée comme « Object ».
L'instruction « Set » crée l'instance et exécute le constructeur.

Code : Tout sélectionner

	Dim a As Object
	Set a = New Point
	a.X = 4
	a.Y = 1
	MsgBox a._X
Le code ci_dessous est fonctionnellement équivalent au précédent et en constitue une variante plus concise.
Toutefois il faut comprendre que le constructeur ne sera exécuté qu'à la première utilisation de la variable « a », soit à l'instruction « a.X = 4 ». Ceci signifie que pour chaque instruction entre la déclaration de la variable et sa première utilisation l'interpréteur insérera du code pour savoir s'il y a lieu de déclencher le constructeur.
Personnellement je privilégierai en conséquence la forme précédente.

Code : Tout sélectionner

	Dim a As New Point
	a.X = 4
	a.Y = 1
	MsgBox a._X
Définition de la classe « Circle »

Code : Tout sélectionner

Option Compatible
Option ClassModule

Option Explicit

REM -----------------------------------------------------------------------------------------------------------------------
REM --- Internal Variables																								---
REM -----------------------------------------------------------------------------------------------------------------------

Private _R		As Double
Private _Center	As Object

REM -----------------------------------------------------------------------------------------------------------------------
REM --- CONSTRUCTORS / DESTRUCTORS						        														---
REM -----------------------------------------------------------------------------------------------------------------------
Private Sub Class_Initialize()
'	Default circle = Null circle at axis origin
	_R = 0
	Set _Center = New Point
End Sub		'	Constructor

REM -----------------------------------------------------------------------------------------------------------------------
Private Sub Class_Terminate()
	_R = 0
	Erase _Center
End Sub

REM -----------------------------------------------------------------------------------------------------------------------
REM --- CLASS GET/LET/SET PROPERTIES					        														---
REM -----------------------------------------------------------------------------------------------------------------------

Property Get R As Double
	R = _R
End Property

Public Property Let R(ByVal pValue As Double)
	_R = pValue
End property

REM -----------------------------------------------------------------------------------------------------------------------
Public Property Get Center As Object
	Set Center = _Center
End Property

Property Set Center(ByVal pValue As Object)
	Set _Center = pValue
End property

REM -----------------------------------------------------------------------------------------------------------------------
Public Function Area() As Double
	Area = PI() * R * R
End Function

Public Function Circumference() As Double
	Circumference = 2 * PI() * R
End Function

REM -----------------------------------------------------------------------------------------------------------------------
Public Property Get Dummy As Variant
	Dummy = Null
End Property

REM -----------------------------------------------------------------------------------------------------------------------
REM --- CLASS METHODS	 								        														---
REM -----------------------------------------------------------------------------------------------------------------------

Public Sub MoveHoriz(ByVal pValue)		'	pValue might be negative
	_Center.Move(pValue, 0)
End Sub

Public Sub MoveVert(ByVal pValue)			'	pValue might be negative
	_Center.Move(0, pValue)
End Sub

REM -----------------------------------------------------------------------------------------------------------------------
Public Function IntersectX() As Variant
'	Return intersection points of circle with X-axis
'	Substitute y = 0 in circle equation (x-Cx)2 + (y-Cy)2 = R2
'		=> Equation of degree 2 with unknown x
Dim a As Double, b As Double, c As Double, dDiscr As Double
	a = 1
	b = -2 * _Center.X
	c = (_Center.X ^ 2) + (_Center.Y ^ 2) - (R ^ 2)
	dDiscr = (b ^ 2) - (4 * a * c)

Dim oInterSect1 As Object, oInterSect2 As Object
	Select Case True
		Case dDiscr < 0		:	InterSectX = Array()
		Case dDiscr = 0
			Set oInterSect1 = New Point
			oInterSect.X = -b / (2 * a)
			Set InterSectX = Array(oInterSect)
		Case Else
			Set oInterSect1 = New Point
			Set oInterSect2 = New Point
			oInterSect1.X = (-b - Sqr(dDiscr)) / (2 * a)
			oInterSect2.X = (-b + Sqr(dDiscr)) / (2 * a)
			InterSectX = Array(oInterSect1, oInterSect2)
	End Select
End Function
Spécificités :

Une des variables internes est une instance de la classe « Point ».

Une function, telle « Area », outre les actions qu'elle peut exécuter, retourne de surcroît une valeur. Quelle est la différence entre « Property Get Area() » et « Public Function Area() » ? Il n'y en a pas sauf en ce qui concerne leur traitement par le debugger. Voir plus bas.

Le destructeur « Class_Terminate » contient une instruction « Erase » qui, elle-même, active le destructeur de l'objet « _Center » de type « Point ».

Les méthodes « MoveHoriz » et « MoveVert » font appel à la méthode « Move » de la classe « Point » appliquée à la variable interne « _Center ».

Exemples :

- Avec illustration de l'instruction « With » ainsi que des propriétés en cascade « b.Center.X » :

Code : Tout sélectionner

	Dim a As Object
	Set a = New Point
	a.X = 2
	a.Y = 1
	Dim b As Object
	Set b = New Circle
	With b
		.R = 2
		Set .Center = a
		.MoveHoriz(2)	'	Center becomes (4,1)
		MsgBox "Circle centered on (" & .Center.X & "," & .Center.Y & "). Circumference = " & .Circumference
	End With
	Erase b
- L'exemple suivant illustre la méthode IntersectX qui retourne un tableau de « Points » d'intersection entre une instance de type « Circle » et l 'axe des X : il peut y avoir 0, 1 ou 2 points d'intersection.

Code : Tout sélectionner

	Dim b As Object
	Set b = New Circle
	b.Center.X = 4
	b.Center.Y = 1
	b.R = 2
	Dim vPoints As Variant, i As Integer
	vPoints = b.IntersectX()	'	Return an array of Points objects
	For i = LBound(vPoints) To UBound(vPoints)
		MsgBox vPoints(i).X
	Next i
Debugging :

L'utilisation de Xray est inutile. En effet aucune information utile sur une instance de classe ne proviendra de cet outil. Cependant son exécution sur un tel objet se passe sans douleur.

Le comportement du debugger de l'IDE est différent. Soit l'exécution se trouve à l'intérieur de la classe, dans ce cas les variables internes de l'instance (en plus des variables locales de la routine en cours ...) sont visualisables en mentionnant simplement leur nom. Soit l'exécution est en-dehors de la classe, dans ce cas la visualisation d'une variable passera par le calcul par le debugger de chaque propriété de la classe ! Super, car même si une des propriétés est elle-même une instance de classe, l'arborescence est bien gérée.
Toutefois ceci signifie :
- que si le calcul de la propriété contient une erreur, le debugger commettra la même erreur, d'où l'intérêt parfois d'utiliser temporairement pendant la mise au point « Function » plutôt que « Property Get »;
- que si vous êtes en mode pas-à-pas, le pas-à-pas s'engage à son tour et sous l'impulsion du debugger sur la voie des différentes « Property Get » ..., ce qui entraîne à coup sûr et rapidement un crash de AOO/LibO.

La propriété « Dummy » a été insérée dans chacun des modules de classe simplement parce que le debugger affiche dans l'IDE toutes les propriétés, sauf, bizarrement, la dernière ... ?

En conclusion : visualiser une variable de classe, oui, mais si le calcul des propriétés est au point, et, une fois visualisée, retirer la variable des variables observées avant de poursuivre l'exécution.

Autres remarques :

Basic supporte également le verbe « Implements » comme en VB6. Son usage me paraît cependant peu utile.
VB6 accepte également l'usage dans un module de classe du mot-clé « This » pour désigner l'instance courante en exécution. De plus il permet le passage de l'objet traité comme argument d'une fonction externe au module. Ceci n'est pas possible en Basic, à ma connaissance.
L'héritage entre classes d'objets n'est pas possible. Le verbe « Inherits » n'est implémenté d'ailleurs en VB que dans les versions postérieures à VB6.

J'espère que ces explications vous seront profitables ...
JPL
Dernière modification par JPL le 10 déc. 2012 10:07, modifié 1 fois.
Kubuntu 22.04 / LibO 7.6
Access2Base (LibO).
BaseDocumenter extension (LibO)
ScriptForge (LibO) - Documentation on https://help.libreoffice.org/latest/en- ... bPAR=BASIC
Avatar de l’utilisateur
Churay
ManitOOu
ManitOOu
Messages : 2668
Inscription : 30 avr. 2009 06:54
Localisation : CATALUNYA
Contact :

Re: [Basic] Programmation orientée objet

Message par Churay »

Bonjour

A toutes fins utiles :
Le modérateur a écrit :Aucune question dans ce fil, veuillez poster en section Macro & API
Répondre