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

Re: La Poo pour les nulles

Message par microdevweb »

Faire une méthodes abstraite

Comme vous devez vous en douter, chaque fois la difficulté monte d'un cran. Mais faire une méthode dite abstraire n'est pas si compliqué.

Une structure peut contenir un peux près tous ce que l'on veux et y compris des pointeurs.

Le pointeur qui pour rappel ne contienne que l'adresse de quelque chose comme une variable ou un procédure, peuvent contenir l'adresse d'une procédure qui peut être prototypée.

Et c'est là que l'on va vraiment pouvoir s'amuser comme des petit fouts :mrgreen: .

Bon pour ceux qui on fait un peu de C, on doit faire des prototypes pour les fonction avant de pouvoir les utilisées. En PureBasic pas et c'est très bien ainsi, par contre on peut créer un prototype pour un pointeur qui pointera lui même sur l'adresse de la fonction.On pourra donc utiliser le dit pointeur comme un appel de procédure standard.

Remarque : fonctionne avec * ou sans

Exemple:

Code : Tout sélectionner

Prototype.s p_bonjour(nom.s)
Prototype.s p_byeBye()
Prototype p_additionne(n1,n2)
Structure teste
  ditBonjour.p_bonjour  ; Remarque : fonctionne avec * ou sans 
  ditByeBye.p_byeBye
  *additionne.p_additionne ; cela aurait fonctionné sans *
EndStructure
Procedure bonjour(nom.s)
  Debug "Bonjour "+nom 
EndProcedure
Procedure hello(nom.s)
  Debug "Hello "+nom 
EndProcedure
Procedure aurevoir()
  Debug "Au revoir et bonne journée"
EndProcedure
Procedure bye()
  Debug "Bye bye have a nice day"
EndProcedure
Procedure additionne(n1,n2)
  Debug Str(n1+n2)
EndProcedure
Define.teste mesMethodes,mesAutreMethode
; je renseignes les adresses des procédure sans paramètre
mesMethodes\ditBonjour = @bonjour()
mesMethodes\ditByeBye = @aurevoir()
mesMethodes\additionne = @additionne()

mesAutreMethode\ditBonjour = @hello()
mesAutreMethode\ditByeBye = @bye()
mesAutreMethode\additionne = @additionne()

; terste
mesMethodes\ditBonjour("Piere")
mesAutreMethode\ditBonjour("Pierre")
mesMethodes\ditByeBye()
mesAutreMethode\ditByeBye()
mesMethodes\additionne(10,8)
mesAutreMethode\additionne(30,60)
Comme vous pouvez le constaté les pointeurs et les prototypes c'est très puissant et offre énormément de possibilités.

Et c'est cette technique que nous allons utilisée pour créer nos méthodes abstraites.

Aller fini la parlote voici comment faire

Code : Tout sélectionner



Prototype p_draw(*this) ; il est indispensable de récupérer l'adresse de l'instance
                        ; pour cette exemple je ne vais pas implémenté les getters et setters


Interface Forme
  draw()
EndInterface
Interface Rectangle Extends forme
  ; vide dans le cadre du tuto
EndInterface
Interface Cercle Extends forme
  ; vide dans le cadre du tuto
EndInterface
; cette classe sera abstraite car elle n'aura pas de constructeur
Structure _forme
  *methods
  x.l
  y.l
  draw.p_draw ; la fameuse méthode abstraite
EndStructure
Structure _rectangle Extends _forme
  w.l
  h.l
EndStructure
Structure _cercle Extends _forme
  r.l
EndStructure
; méthode abstraite de rectangle
Procedure drawRectangle(*this._rectangle)
  With *this
    Debug "Je dessine le rectangle "+Str(\w)+" sur "+Str(\h) 
  EndWith
EndProcedure
; méthode abstraite de cercle
Procedure drawCercle(*this._cercle)
  With *this
    Debug "Je dessine un beau cercle de "+Str(\r)+" de rayon" 
  EndWith
EndProcedure
; méthode abstraite de forme
Procedure draw(*this._forme)
  With *this
    \draw(*this)  ; j'appelle la procédure selon la classe fille
                  ; polymorphisme bricolé :)
  EndWith
EndProcedure
; constructeur de rectangle
Procedure newRectangle(x,y,w,h)
  Protected *this._rectangle = AllocateStructure(_rectangle)
  With *this
    ; comme pour ce tuto il n'y pas de méthodes pour les classes filles
    ; je passe directement les adresses
    \methods = ?S_forme
    \x = x
    \y = y
    \w = w
    \h = h
    \draw = @drawRectangle() ; je renseigne l'adresse de la procédure appropriée
    ProcedureReturn *this
  EndWith
EndProcedure
; constructeur de cercle
Procedure newCercle(x,y,r)
  Protected *this._cercle = AllocateStructure(_cercle)
  With *this
    ; comme pour ce tuto il n'y pas de méthodes pour les classes filles
    ; je passe directement les adresses
    \methods = ?S_forme
    \x = x
    \y = y
    \r = r
    \draw = @drawCercle() ; je renseigne l'adresse de la procédure appropriée
    ProcedureReturn *this
  EndWith
EndProcedure

DataSection
  S_forme:
  Data.i @draw()
EndDataSection

; aller on teste
Define.Forme monRectangle1,monRectangle2,monCercle1,monCercle2

monRectangle1 = newRectangle(10,10,800,200)
monRectangle2 = newRectangle(10,10,400,100)
monCercle1 = newCercle(20,50,60)
monCercle2 = newCercle(20,50,120)

monRectangle1\draw()
monRectangle2\draw()
monCercle1\draw()
monCercle2\draw()

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 nuls

Message par microdevweb »

Faire tout un soft en style Poo peut demander beaucoup de travail, donc je viens de démarrer un projet pour faciliter tout cela.

Il sera en deux étapes
  • un model exploitable
  • un interface graphique
Voici le genre de code qu'il faudra taper, et cela créera la structure de toutes les classes dans des fichiers séparé et répertorié.

Code : Tout sélectionner

; *************************************************************************
; AUTHOR          : MicrodevWeb 
; PROJECT NAME    : Poo maker
; PROJECT VERSION : 1.0
; PROJECT DATE    : 2018/09/05        
; DESIGNED WITH   : PB 5.62
; *************************************************************************
IncludePath "Modules/"
XIncludeFile "Model.pbi"
UseModule Model
Global.Project drawingProject = newProject("drawing")
mModel.Package = drawingProject\addPackage(newPackage("Model"))
mForm.AbstractClass = mModel\addClass(newAbstractClass("Form"))
mForm\addMember(newPublicMember("pos_x",#MB_TYPE_INTEGER))
mForm\addMember(newPublicMember("pos_y",#MB_TYPE_INTEGER))

mCircle.PublicClass = mModel\addClass(newPublicClassEtendsOf("cCircle",mForm))
mCircle\addMember(newPublicMember("radius",#MB_TYPE_INTEGER))

mRectangle.PublicClass = mModel\addClass(newPublicClassEtendsOf("Rectangle",mForm))
mRectangle\addMember(newPublicMember("width",#MB_TYPE_INTEGER))
mRectangle\addMember(newPublicMember("heigth",#MB_TYPE_INTEGER))


drawingProject\build("C:\Users\microdevweb\OneDrive\POO_MAKER\Teste")
Windows 10 64 bits PB: 5.70 ; 5.72 LST
Work at Centre Spatial de Liège
Répondre