La POO pour les nuls

Informations pour bien débuter en PureBasic
Avatar de l’utilisateur
microdevweb
Messages : 1798
Inscription : mer. 29/juin/2011 14:11
Localisation : Belgique

La POO pour les nuls

Message par microdevweb »

Bonjour à tous,

J'avais abandonné un peux Purebasic car il n'est pas orienté objet. Maintenant j'y reviens.

Non non vous n'avez rien raté je vous rassure, Purebasic n'est toujours pas orienté objet :mrgreen: par contre j'ai trouvé pas mal d'astuces pour développé en orienté objet et avec Purebasic.

Plan du tutoriel : Pour résumé il est tout à fait possible de développé avec la philosophie Poo dans PureBasic du moment ou on est organisé.

Evidemment on n'aura pas le confort de Java ou C#, on sera plus proche du style C++ (avec évidement moins de possibilités comme la surcharge de méthodes) le gros manquement sera surtout de ne pas pouvoir appeler les commandes en cascade.

exemple :

Code : Tout sélectionner

; impossible
monObjet\getPosition()\getPosX()
; possible
P.Position = monObjet\getPosition()
p\getPosX()
L’exécutable ne devrais pas perdre en qualité puisque on ne joue en vérité qu'avec des pointeurs.
Dernière modification par microdevweb le jeu. 06/sept./2018 14:17, modifié 18 fois.
Windows 10 64 bits PB: 5.70 ; 5.72 LST
Work at Centre Spatial de Liège
Avatar de l’utilisateur
microdevweb
Messages : 1798
Inscription : mer. 29/juin/2011 14:11
Localisation : Belgique

Re: La Poo pour les nulles

Message par microdevweb »

Mais c'est quoi au juste la Poo?

La Poo c'est créer des classes ? Une classe ne peut pas être utilisée directement, on en crée une instance qui par contre pourra être utilisée.

Une classe c'est comme une grosse boîte qui va contenir.
  • des membres nommé également attributs (des variables si vous préféré)
  • des méthodes (qui ne sont rien d'autre que des procédure ou fonctions)
Dans le principe il peut y avoir trois types d'intervenants
  • Le concepteur qui aura accès à tout.
  • L'utilisateur qui aura accès uniquement a ce que le concepteur permet.
  • L'utilisateur avancé qui en créant une classe héritée aura accès à plus ou moins de chose et ceci toujours selon les permissions du concepteur
Pour faire un petit comparatif, une classe c'est un peux comme une structure qui contient en plus des fonctions (note une structure le permet aussi) mais par contre à la quel on a pas accès à tous les paramètres.

Il évident que pour faire quelque chose on ne se contente pas d'une seul classe mais de plusieurs.
Windows 10 64 bits PB: 5.70 ; 5.72 LST
Work at Centre Spatial de Liège
Avatar de l’utilisateur
microdevweb
Messages : 1798
Inscription : mer. 29/juin/2011 14:11
Localisation : Belgique

Re: La Poo pour les nulles

Message par microdevweb »

Mais ça sert à quoi la Poo ?

Beaucoup dirons à nous faire ch..... :mrgreen: , mais le but est principalement de divisé son code en plusieurs sous programme ou module indépendant non compilé et dynamique.

Normalement un classe si elle bien développée doit pouvoir être modifiée sans altérer le fonctionnement du code qui les utilise.

A la base la Poo a surtout été conçue pour le travail en équipe. Tel personne créant tel classe qui pouvait être utilisée par d'autres sans devoir se soucier du fonctionnement de la dite classes.

Comparer cela à votre voiture, vous savez la conduite mais vous ne s'avez pas forcément comment elle fonctionne, ça c'est le rôle du mécano. Si le mécano change quelque chose à votre voiture, cela ne changera pas vos commandes de conduite (volant,pédales etc). Par contre s'il ajoute quelque chose (des feux antibrouillard par exemple) et bien vous aurez un bouton de plus pour les allumer et éteindre.

Donc en développent de cette manière on va créer des classes qui seront utilisée par nous ou d'autres et pourrons être utilisées dans n'importe quel projet.
Windows 10 64 bits PB: 5.70 ; 5.72 LST
Work at Centre Spatial de Liège
Avatar de l’utilisateur
microdevweb
Messages : 1798
Inscription : mer. 29/juin/2011 14:11
Localisation : Belgique

Re: La Poo pour les nulles

Message par microdevweb »

Les avantages.

Le gros avantage est principalement de scinder son code en plusieurs modules autonomes.

Un classe est plus facilement réutilisable qu'une simple procédure.

Son fonctionnement est masqué cela la rend plus facile d'accès et limite les risques d'erreur.

Cela évite souvent de devoir faire le même travaille plusieurs fois.

Les instance de classes une fois créée possède leurs propres attributs et son utilisable comme des objets à part entière.
Windows 10 64 bits PB: 5.70 ; 5.72 LST
Work at Centre Spatial de Liège
Avatar de l’utilisateur
microdevweb
Messages : 1798
Inscription : mer. 29/juin/2011 14:11
Localisation : Belgique

Re: La Poo pour les nulles

Message par microdevweb »

Les inconvénients ?
Pour le concepteur
  • En général on va écrire plus de code.
  • Cela vas demander plus d'analyse
  • Surtout en PureBasic, il faudra travaillé de manière rigoureuse
Pour l'utilisateur
  • Il n'aura pas toujours accès directement a tel ou tel attribut mais devra passé des sous-classes
Windows 10 64 bits PB: 5.70 ; 5.72 LST
Work at Centre Spatial de Liège
Avatar de l’utilisateur
microdevweb
Messages : 1798
Inscription : mer. 29/juin/2011 14:11
Localisation : Belgique

Re: La Poo pour les nulles

Message par microdevweb »

L'encapsulation

C'est le principe de la voiture, l'utilisateur peut la conduire mais pas touché au moteur.

Ainsi les membres seront privés à la classe, pour consulter ou modifier la valeur d'un attribut on devra passé par des méthodes que l'on nome généralement getters ou setters.
Idem pour une voiture, pour voir ce qui reste d'essence on vous à mis un jauge, vous ne devrez pas vous rendre au réservoir avec une baguette de bois (c'est beau le progres :mrgreen: )

Cela est vraiment capital dans le principe de pouvoir modifié la classe sans influencer le bon fonctionnement du code qui les utilises.

Un exemple :

Une classe qui dessinerais des rectangle de couleur.

Dans un premier temps elle utilise la bibliothèque "2dDrawing" et pas d'encapsulation, ainsi l'utilisateur a entré directement la valeur.

Ensuite le concepteur décide d'utiliser "Vector" en lieux et place de "2dDrawing". Aille catastrophe plus rien de fonctionne. Et oui malheureusement "Vector" demande une couleur avec alpha.

Si le concepteur avait utilisé l'encapsulation, il n'aurais eu qu'a changé le setter et ainsi a transformé la couleur reçue en lui ajoutant l'alpha.

Donc n'oublier n'oublier pas c'est vraiment IMPORTANT :twisted:
Windows 10 64 bits PB: 5.70 ; 5.72 LST
Work at Centre Spatial de Liège
Avatar de l’utilisateur
microdevweb
Messages : 1798
Inscription : mer. 29/juin/2011 14:11
Localisation : Belgique

Re: La Poo pour les nulles

Message par microdevweb »

L'héritage

C'est la propriété d'une classe de pouvoir hérité d'un autre classe. Elle hérite ainsi de tous ses membres et méthodes.

Cependant les accès seront limités et définit par le concepteur de la classe mère.

Dans une classe fille on aura accès à tous les membres et méthodes qui on été déclaré Public ou Protégé. Nous aborderons les portées des membres et méthodes plus tard.

Un exemple :

Penons une classe dessin qui pourrait contenir des rectangles et des cercles, on peut dire quel contient des formes géométriques. On fera donc ceci.

Classe Forme
Classe Rectangle Hérite de Forme
Classe Cercle Hérite de Forme

L'héritage est vraiment utile et très puissant
Windows 10 64 bits PB: 5.70 ; 5.72 LST
Work at Centre Spatial de Liège
Avatar de l’utilisateur
microdevweb
Messages : 1798
Inscription : mer. 29/juin/2011 14:11
Localisation : Belgique

Re: La Poo pour les nulles

Message par microdevweb »

Le polymorphisme

Aille c'est encore ce machin là? :twisted:

Cette propriété n'a de sens qu'avec des classes héritées. Cela consiste à dire que si j'appelle la méthodes (dite abstraite) depuis une classe mère le compilateur ira cherché la bonne méthode de la classe fille.

Houla... j'ai rien pigé... 8O

C'est vrai que de première abord ce n'est pas très claire.

Reprenons mon exemple de Classe dessin, qui peut contenir des instances de Classe Forme.

Cette classe ne sait pas à qui elle a à faire. Un rectangle, un cercle ? Et pourtant on ne dessine pas un rectangle comme un cercle.

Alors comment faire ?

Et bien dans la classes Forme nous allons créer un méthodes abstraite que nous nommerons par exemple Draw (en Anglais ça fait tout de suite plus pro :mrgreen: )

Heuuuuu c'est quoi une méthode abstraite !!! 8O

Une méthode abstraite ne reprend que le prototype de fonction donc le nom et éventuellement différents arguments mais sans corps de fonction (donc cela ne fait strictement rien).

Ensuite pour toutes les classes filles de Forme, nous créerons la méthode selon le prototype et cette fois ci avec le corps adapté à la classe.

Oufffffff 8O voila j'espère que vous avez compris.

Donc vous l'aurez compris le polymorphisme ça peut être vraiment cool.
Windows 10 64 bits PB: 5.70 ; 5.72 LST
Work at Centre Spatial de Liège
Avatar de l’utilisateur
microdevweb
Messages : 1798
Inscription : mer. 29/juin/2011 14:11
Localisation : Belgique

Re: La Poo pour les nulles

Message par microdevweb »

Les classes abstraites

Une classe abstraite est une classe qui ne peut pas être instanciée (elle peut pas faire des bébés :mrgreen: ).

Heu ben ça sert à quoi alors ??? 8O

Reprenons mon exemple de classes dessin. (oui je sais je radote :mrgreen: )

Elle est constituée de Formes géométriques, mais se serait stupide de pouvoir lui ajouté une forme géométrique sans stipuler de quel forme il s'agis.

Donc la classe forme sera une classe abstraite.
Windows 10 64 bits PB: 5.70 ; 5.72 LST
Work at Centre Spatial de Liège
Avatar de l’utilisateur
microdevweb
Messages : 1798
Inscription : mer. 29/juin/2011 14:11
Localisation : Belgique

Re: La Poo pour les nulles

Message par microdevweb »

Comment faire avec Purebasic ?

Purebasic possède pas mal d'outils que nous utiliserons pour créer nos classes
  • Les structure (cela nous servira de container pour une classe)
  • Les interfaces (cela nous servira à rendre une méthodes publique)
  • Les pointeurs (l'a on vas vraiment en abusé :mrgreen: )
  • AllocateStructure (cela nous servira à créer une instance de classe)
  • Les modules (cela nous servira à créer des package de classes)


On va voir tout cela en détail
Windows 10 64 bits PB: 5.70 ; 5.72 LST
Work at Centre Spatial de Liège
Avatar de l’utilisateur
microdevweb
Messages : 1798
Inscription : mer. 29/juin/2011 14:11
Localisation : Belgique

Re: La Poo pour les nulles

Message par microdevweb »

une simple classe

Bon allez voir ce n'est pas la mer à boire, même s'il il y a plus de code qu'en procédural cela m'aura pris moins de 5 minutes.

Code : Tout sélectionner

; Une simple classe avec PureBasic
; une classe contact
; les méthodes publiques
EnableExplicit
Interface Contact
  getNom.s()
  setNom(nom.s)
  getPrenom.s()
  setPrenom(prenom.s)
EndInterface
; container de la classes
Structure _contact ; j'ajoute un _  pour dire que c'est priver (ce n'est pas obligatoire)
  *methods         ; pointeur des methodes publiques
  nom.s
  prenom.s
EndStructure

; les Getters et les setters
Procedure.s getNom(*this._contact) ; *this est l'adresse de l'instance retourner par l'interface
  With *this
    ProcedureReturn \nom
  EndWith
EndProcedure

Procedure setNom(*this._contact,nom.s) 
  With *this
    \nom = nom
  EndWith
EndProcedure

Procedure.s getPrenom(*this._contact) 
  With *this
    ProcedureReturn \prenom
  EndWith
EndProcedure

Procedure 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_meth ; copie des adresses de méthodes
    \nom = nom
    \prenom = prenom
    ProcedureReturn *this
  EndWith
EndProcedure

; adresses des méthodes publiques
DataSection
  S_meth:
  Data.i @getNom()
  Data.i @setNom()
  Data.i @getPrenom()
  Data.i @setPrenom()
  E_meth:
EndDataSection

; aller on teste tous ça :)

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

Windows 10 64 bits PB: 5.70 ; 5.72 LST
Work at Centre Spatial de Liège
Avatar de l’utilisateur
microdevweb
Messages : 1798
Inscription : mer. 29/juin/2011 14:11
Localisation : Belgique

Re: La Poo pour les nulles

Message par microdevweb »

Faire un package de classes

Bon soyons claire, il est vraiment rare d'avoir une classes qui ne fait pas appel à d'autres. Donc si l'on pratique comme dans mon premier exemple cela va vite être le bor..... :twisted: .

Comme nous somme des gens civilisés et que nous ne voulons pas de cela on va s'organiser.

On va créer un package de nos classe (ouais ça c'est vrai en java) alors un espace de nom (ouais ça c'es vrai en c++) bon ben en PureBasic on vas créer un module (ben voila tu vois quand tu veux).

Dans ce module on va importer tous nos fichiers classes (bon dans le cadre du tuto je ne le ferais pas).

Dans un fichier qui sera le premier on placera toutes nos structure.

Ensuite un fichier par classe, dans l'ordre des appels (pour ne pas devoir tout déclaré avec Declare

Pour éviter tous les conflits de nom de procédure on fera précédé le nom de la procédure par par exemple (Procedure _maclasse_maProcedure()
)

Les label de Datasection exemple (S_maclasse: E_maclasse:)

Et comme un petit exemple vaut mieux q'un trop long discourt voila

Code : Tout sélectionner

DeclareModule Contact
  Interface Contact
    getNom.s()
    setNom(nom.s)
    getPrenom.s()
    setPrenom(prenom.s)
  EndInterface
  
  Declare newContact(nom.s,prenom.s)
EndDeclareModule
Module Contact
  ; IncludePath "Contact_Classes/"
  ;XIncludeFile "Structure.pbi"
  ;XIncludeFile "Contact.pbi"
  
  ; le contenu de Structure.pbi
  Structure _contact 
    *methods         
    nom.s
    prenom.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
  
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
Windows 10 64 bits PB: 5.70 ; 5.72 LST
Work at Centre Spatial de Liège
Avatar de l’utilisateur
omega
Messages : 617
Inscription : sam. 26/nov./2011 13:04
Localisation : Alger

Re: La Poo pour les nulles

Message par omega »

Bonjour Microdevweb et merci beaucoup pour ce joli tuto surtout au niveau des sous-classes et pointeurs, pour ma part, j'ai toujours voulu approfondir mes connaissances dans ce domaine mais voilà, tu viens de prendre une bonne initiative que j'apprécie beaucoup. J'aurais souhaité, si possible, d'insister un peu plus longtemps sur chaque chapitre pour que moi (et d'autres nuls comme moi) puissent mieux comprendre les leçons...
Merci et bonne continuation.
Win7 (x64) 64 bits Pb 5.72
Avatar de l’utilisateur
microdevweb
Messages : 1798
Inscription : mer. 29/juin/2011 14:11
Localisation : Belgique

Re: La Poo pour les nulles

Message par microdevweb »

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()

Dernière modification par microdevweb le mer. 05/sept./2018 14:51, modifié 4 fois.
Windows 10 64 bits PB: 5.70 ; 5.72 LST
Work at Centre Spatial de Liège
Avatar de l’utilisateur
Micoute
Messages : 2522
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: La Poo pour les nulles

Message par Micoute »

Très bon travail, merci pour cet excellent tutoriel.
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 5.73 PB 6.00 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Répondre