Introduction
Bon pour éviter que ce soit lourds je vais donner des exemples puis donner des commentaires pour que ce soit claire.
premier exemple on va prendre une voiture.
Notre voiture possède un moteur des roues et des portes (oui c'est tout on ira pas plus loin sinon on a pas finit)
Nous avons donc les classes suivantes
-Voiture
-Roue
-Porte
-Moteur
une voiture comporte
-un moteur
-quatre roues
-deux portes(oui c'est une petite voiture :p)
ce qui donne le schéma suivant

Bien sur il n'est pas complet il manque la liste des attributs des structures et la liste des procédures.
Code
Premiere Version
Voyons maintenant ce que sa donne en PureBasic mais sans utiliser d'interface plutôt lourde.
On commence par crées les attributs des Classes
Code : Tout sélectionner
Structure Roue
Diametre.l
EndStructure
Structure Moteur
Puissance.l
EndStructure
Structure Porte
VitreTeinte.b
EndStructure
Structure Voiture
*Roue.Roue[4]
*Moteur.Moteur
*Porte.Porte[2]
EndStructure
un objet ? c'est quoi ? c'est juste une allocation mémoire de la taille de la structure.
mais notre objet ne se construit pas par la bonne volonté du saint esprit c'est pourquoi pour chaque classe il faut un constructeur. Un constructeur c'est juste une procédure qui initialise l'objet.
On commence donc par la classe Roue et on écrit son constructeur.
Code : Tout sélectionner
Procedure NewRoue(Diametre.l)
Protected *this.Roue = AllocateMemory(SizeOf(Roue))
*this\Diametre = Diametre
ProcedureReturn *this
EndProcedure
Code : Tout sélectionner
Procedure Roue_Gonfler(*this.Roue)
Debug "Hop on a gonfléé la roue"
EndProcedure
Code : Tout sélectionner
Macro New(Type)
Protected *this.Type = AllocateMemory(SizeOf(Type))
EndMacro
Procedure NewRoue(Diametre.l)
New(Roue)
*this\Diametre = Diametre
ProcedureReturn *this
EndProcedure
Code : Tout sélectionner
Procedure NewVoiture(Nom.s)
New(Voiture)
Select Nom
Case "tingo"
*this\Roue[0] = NewRoue(40)
*this\Roue[1] = NewRoue(40)
*this\Roue[2] = NewRoue(40)
*this\Roue[3] = NewRoue(40)
*this\Porte[0] = NewPorte(#False)
*this\Porte[1] = NewPorte(#False)
*this\Moteur = NewMoteur(60)
Case "panda"
*this\Roue[0] = NewRoue(20)
*this\Roue[1] = NewRoue(20)
*this\Roue[2] = NewRoue(20)
*this\Roue[3] = NewRoue(20)
*this\Porte[0] = NewPorte(#True)
*this\Porte[1] = NewPorte(#True)
*this\Moteur = NewMoteur(120);surpuissant la panda
Case "fred"
Debug "Oo"
ProcedureReturn #Null
Default
Debug "hé sa existe pas sa"
ProcedureReturn #Null
EndSelect
ProcedureReturn *this
EndProcedure
Procedure Voiture_Avancer(*this.Voiture)
Debug "GPS en panne -_-"
EndProcedure
Procedure Voiture_Rouler(*this.Voiture)
Protected n
For n = 0 To 3
Roue_Gonfler(*this\Roue[n])
Next n
Porte_Ouvrir(*this\Porte[0])
Porte_Fermer(*this\Porte[0])
Moteur_Demarer(*this\Moteur)
Repeat
For n = 0 To 3
If Roue_Creve(*this\Roue[n]) = #True
Break
EndIf
Next n
Voiture_Avancer(*this)
ForEver
EndProcedure
Define.Voiture *MaVoiture = NewVoiture("panda")
Voiture_Rouler(*MaVoiture)
Intérêt ?
c'est bien jolie mais sa sert pas a grand chose ! Oui effectivement si vous avez toujours programmé en procédural l'intérêt au premier abord est plutôt limité, donc voici les avantages.
Première chose faciliter le travaille en équipe :
On définit les classes méthodes et procédure sur un schéma et on distribue le codage des classes entre les membres de l'équipe.
Seconde chose si on revient dans son code de 6 000 ligne trois mois après c'est très simple de se retrouver .
Troisio le problème est plus facile a modéliser en objet que en procédurale.
La POO n'est pas l'invention du siècle et n'est pas forcement adapté a tout le monde si vous et le procedurale c'est une histoire d'amour inutile de vous forcer a coder en POO., surtout pour les petits projets.
Seconde version
La seconde méthode pour coder ceci en POO est d'utiliser les interfaces. Il existe bien des tutos sur l'utilisation des interfaces donc je ne vais pas donner de détails mais je vous invite a aller faire un tour dans la section tuto si cela vous intéresse.
Si vous suivez le schéma plus haut vous devriez avoir quatre interface.
Troisieme version
Bon oui il existe une autre version c'est d'utiliser Chronos (oui j'en profite pour faire un peu de PUB

Sous Chronos nous avons un jolie précompilateur qui permet de respecter au mieux un schéma UML sans dénaturer le PureBasic mais trêve de blabla je vais reprendre ce que nous avons codé plus haut.
Code : Tout sélectionner
Structure Roue
Diametre.l
EndStructure
Procedure NewRoue(Diametre.l)
Protected *this.Roue = AllocateMemory(SizeOf(Roue))
*this\Diametre = Diametre
ProcedureReturn *this
EndProcedure
Procedure Roue_Gonfler(*this.Roue)
Debug "Hop on a gonfléé la roue"
EndProcedure
Code : Tout sélectionner
Class Roue
Diametre.l
Procedure Roue(Diametre.l)
*this\Diametre = Diametre
EndProcedure
Procedure Gonfler()
Debug "Hop on a gonflée la roue de diamètre : " + str(*this\Diametre)
EndProcedure
EndClass
En effet comme je n'ai pas inventé la roue je l'ai copié sur certain language que j'utilise souvent comme java ou c++.
pour utiliser notre classe deux méthodes.
la première est totalement interprété par le compilateur.
Code : Tout sélectionner
Define.Roue *ptr = New Roue() ;il est important de définir le pointeur comme une Roue sinon le précompilateur ne peut pas savoir d'où vient la méthode Gonfler()
*ptr.Gonfler()
Code : Tout sélectionner
*ptr=New_Roue()
Roue_Gonfler(*ptr)
Comme je suis ultra faignant j'ai ajouté quelques astuces ce qui permet de faire ceci
Code : Tout sélectionner
Class Roue
Diametre.l = 24
Procedure Gonfler()
Debug "Hop on a gonflée la roue de diamètre : " + str(*this\Diametre)
EndProcedure
EndClass
Généralités
Ce qui va suivre vient de mes cours de génie logiciel donc vous n'êtes pas obligé de tout respecter c'est juste histoire de normaliser nos codes structuré en POO.
Première chose une Classe commence par une majuscule et un attribut et une méthode par une minuscules. Si votre attribut ou votre méthode est un mot composé il devrait être écrit de la maniérè suivante : monAttribut.
Pure ne fait pas la différence mais celui qui lit le code si !
Je vous conseille d'utiliser EnableExplicit (sous Chronos c'est ajouté par le précompilateur) et de protéger tout les variables de vos procédures grâce au mot clé "protected".
Geteur et Seteur
Sous ces noms barbares d'un anglicisme douteux se cache une normalisation qui fait que votre code objet est bien codé ou non. En effet en POO a moins que cela soit absolument nécessaire on ne peut se permettre d'accéder ou de modifier un attribut en dehors de la classe, c'est pourquoi on a inventé les méthodes magiques set et get.
Par exemple dans notre classe Roue si l'on veut changer de diamètre on peut faire *ptr\Diametre = #monNouveauDiametre mais en dehors de la classe c'est une hérésie.
il faut donc crée une méthode "setDiametre(nouveauDiametre)" pareil pour lire le diametre l'on doit créer une méthodes "getDiametre()".
Mais cela va ralentir nôtre code car on doit faire un appel de procédure ? Oui c'est exacte mais cela améliore la lisibilité du code, mais comme je vous le disait vous n'êtes pas obligé de prendre ceci au pied de la lettre.
Méthodes Statiques
Nous avons vue les méthodes, ces jolies procédures liées a une allocation mémoire que nous appelons objet. Oui mais il existe des procédures qui ne sont pas lié a un objet.
Exemple la fonction Sin(Angle.f) de pure basic elle n'est pas liée a un objet mais elle est liée a la classe Math c'est donc une méthode dite statique.
sous Chronos elle sont définie comme ceci.
Code : Tout sélectionner
Class Math
Static Procedure sin(Angle.f)
procedurereturn sin(Angle)
EndProcedure
EndClass
debug Math::sin(24)
le reste a venir ...