Faire une classe héritée
Evidemment c'est la que ça ce complique un peux.
Pour les structures et les interfaces pas de problème on ajoutera seulement un extends.
Par contre le problème sera pour les méthodes publique, les interface vont tout lire dans le même pointeur. Alors comment faire
On va créer un super constructeur (uniquement pour empiler les adresses de méthodes)
Le principe on alloue l'espace mémoire nécessaire, ensuite on copie les adresses les une à la suite des autre.
Bon je l'avoue c'est plus ou moins compliqué, donc je vais créer une macro que vous n'aurez plus q'ua utilisé sans trop vous soucier du fonctionnement.
Par contre il est très important pour pouvoir utilisé cette macro de respecter la même convention de nommage des noms des datasection .
Cette macro doit être appelée entre les balises Width et EndWith et en premier juste arpès l'intanciation avec AllocateStructure
Code : Tout sélectionner
Macro SuperConstructor(mother,daugther,methods)
; allocate memory space requiered
methods = AllocateMemory((?E#mother - ?S#mother)+(?E#daugther - ?S#daugther))
; empil address
MoveMemory(?S#mother,methods,(?E#mother - ?S#mother))
MoveMemory(?S#daugther,methods + (?E#mother - ?S#mother),(?E#daugther - ?S#daugther))
EndMacro
pour que je vous compreniez mieux, voici en clair ce que ma écrit la macro
Code : Tout sélectionner
*this\methods = AllocateMemory((?E_contact - ?S_contact)+(?E_client - ?S_client))
MoveMemory(?S_contact,*this\methods,(?E_contact - ?S_contact))
MoveMemory(?S_client,*this\methods + (?E_contact - ?S_contact),(?E_client - ?S_client))
D’où je rappelle l'importance de respecter le nommage des datasection
Et voici un exemple complet avec une classe client qui hérite de contact.
Code : Tout sélectionner
DeclareModule Contact
Interface Contact
getNom.s()
setNom(nom.s)
getPrenom.s()
setPrenom(prenom.s)
EndInterface
Interface Client Extends Contact
getNumeroTva.s()
setNumeroTva(numero.s)
EndInterface
Declare newContact(nom.s,prenom.s)
Declare newClient(nom.s,prenom.s,numeroTva.s)
EndDeclareModule
Module Contact
Macro SuperConstructor(mother,daugther,methods)
; allocate memory space requiered
methods = AllocateMemory((?E#mother - ?S#mother)+(?E#daugther - ?S#daugther))
; empil address
MoveMemory(?S#mother,methods,(?E#mother - ?S#mother))
MoveMemory(?S#daugther,methods + (?E#mother - ?S#mother),(?E#daugther - ?S#daugther))
EndMacro
; IncludePath "Contact_Classes/"
;XIncludeFile "Structure.pbi"
;XIncludeFile "Contact.pbi"
;XIncludeFile "Client.pbi"
; le contenu de Structure.pbi
Structure _contact
*methods
nom.s
prenom.s
EndStructure
Structure _client Extends _contact
n_tva.s
EndStructure
; le contenu de Contact.pbi
; les Getters et les setters
Procedure.s _contact_getNom(*this._contact) ; *this est l'adresse de l'instance retourner par l'interface
With *this
ProcedureReturn \nom
EndWith
EndProcedure
Procedure _contact_setNom(*this._contact,nom.s)
With *this
\nom = nom
EndWith
EndProcedure
Procedure.s _contact_getPrenom(*this._contact)
With *this
ProcedureReturn \prenom
EndWith
EndProcedure
Procedure _contact_setPrenom(*this._contact,prenom.s)
With *this
\prenom = prenom
EndWith
EndProcedure
; le constructeur
Procedure newContact(nom.s,prenom.s)
; instanciation de la classe
Protected *this._contact = AllocateStructure(_contact)
With *this
\methods = ?S_contact ; copie des adresses de méthodes
\nom = nom
\prenom = prenom
ProcedureReturn *this
EndWith
EndProcedure
; adresses des méthodes publiques
DataSection
S_contact:
Data.i @_contact_getNom()
Data.i @_contact_setNom()
Data.i @_contact_getPrenom()
Data.i @_contact_setPrenom()
E_contact:
EndDataSection
; le contenu de client
; les Getters et les setters
Procedure.s _client_getN_tva(*this._client)
With *this
ProcedureReturn \n_tva
EndWith
EndProcedure
Procedure.s _client_setN_tva(*this._client,n_tva.s)
With *this
\n_tva = n_tva
EndWith
EndProcedure
; le constructeur
Procedure newClient(nom.s,prenom.s,numeroTva.s)
; création de l'instance de classe
Protected *this._client = AllocateStructure(_client)
With *this
; on appelle le super constructeur
SuperConstructor(_contact,_client,\methods)
\nom = nom
\prenom = prenom
\n_tva = numeroTva
ProcedureReturn *this
EndWith
EndProcedure
DataSection
S_client:
Data.i @_client_getN_tva()
Data.i @_client_setN_tva()
E_client:
EndDataSection
EndModule
; aller on teste tous ça :)
; import du module
UseModule Contact
Define.Contact Pierre,Alain,Jacques
Pierre = newContact("Duval","Pierre")
Alain = newContact("Dupond","Alain")
Jacques = newContact("Morteau","Jacques")
; Et hop un petit debug
Debug Pierre\getNom()+" "+Pierre\getPrenom()
Debug Alain\getNom()+" "+Alain\getPrenom()
Debug Jacques\getNom()+" "+Jacques\getPrenom()
; un petit teste dans une liste
Define NewList mesContact.Contact()
Define i
For i = 0 To 10
AddElement(mesContact())
mesContact() = newContact("Nom " + Str(i),"Prénom " + Str(i))
Next
ForEach mesContact()
Debug mesContact()\getNom()+" "+mesContact()\getPrenom()
Next
Define.Client Micro,SuperGame
Micro = newClient("MicrodevWeb","Pierre","BE523.632.840")
SuperGame = newClient("Super Game","Frank","FR963.672.784")
Debug Micro\getNom()+" "+Micro\getPrenom() +" "+Micro\getNumeroTva()
Debug SuperGame\getNom()+" "+SuperGame\getPrenom() +" "+SuperGame\getNumeroTva()