Page 1 of 1

OOP Without interfaces

Posted: Tue Jun 12, 2012 11:32 pm
by Hydrate
This is just a really basic example I got bored and made when I got home from work today. It demonstrates the creation of a class, inheritance of that class and the creation of objects, all without using interfaces, or anything overly complicated to new users of Purebasic. I have no idea how useful it will be to anyone, but better to post it than for it to go entirely to waste.

Enjoy:

Code: Select all

; Simple Purebasic OOP example

; Format for classes:
;   PROTOTYPES      - Only necessary for methods not in parent classes. Declared first so that the structure can read it.
;   STRUCTURE       - Variables, then methods, order doesnt really matter. - METHODNAME.PROTOTYPE
;   METHODS         - Methods with 'CLASSNAME_' before them to distinguish between them and procedures
;   CONSTRUCTOR     - At the bottom so it can set all of the methods appropriately
; 

;{ Class Rectangle
Prototype Rectangle_size(*this, width.i, height.i);
Prototype Rectangle_move(*this, x.i, y.i);
  
  Structure Rectangle;
    x.i;
    y.i;
    width.i;
    height.i;
    
    size.Rectangle_size;
    move.Rectangle_move;
  EndStructure;
  
  Procedure Rectangle_size(*this.Rectangle, width.i, height.i);
    *this\width = width;
    *this\height = height;
  EndProcedure;
  
  
  Procedure Rectangle_move(*this, x.i, y.i)
    Debug "moving";
  EndProcedure;
  
  ; Constructor
  Procedure Rectangle_(*this.Rectangle);
    *this\size = @Rectangle_size();
    *this\move = @Rectangle_move();
  EndProcedure;
;}



;{ Class ColouredRectangle
  Structure ColouredRectangle Extends Rectangle;
    colour.l;
  EndStructure;
  
  ; Method override for size
  Procedure ColouredRectangle_size(*this.ColouredRectangle, width.i, height.i);
    *this\width = width;
    *this\height = height;
    Debug "Coloured sizing instead!";
  EndProcedure;
  
  ; Constructor
  Procedure ColouredRectangle_(*this.ColouredRectangle);
    Rectangle_(*this);
    
    *this\size = @ColouredRectangle_size();
  EndProcedure;
;}



; Rectangle myRect = new Rectangle()
Rectangle_(myRect.Rectangle);
myRect\size(myRect, 20,20);
Debug myRect\width;



; ColouredRectangle mycRect = new ColouredRectangle()
ColouredRectangle_(mycRect.ColouredRectangle);
mycRect\colour = RGB(20,12,20);
mycRect\size(mycRect,22,91);
Debug mycRect\colour;

Re: OOP Without interfaces

Posted: Wed Jun 13, 2012 1:24 am
by Demivec
Thanks for the example.

Re: OOP Without interfaces

Posted: Wed Jun 13, 2012 1:25 am
by skywalk
Seems rather compact and easy to follow.
Is there any need to free memory or a Destructor?

Re: OOP Without interfaces

Posted: Wed Jun 13, 2012 2:03 am
by rsts
Nice :)

Thanks for sharing.

Re: OOP Without interfaces

Posted: Wed Jun 13, 2012 7:28 am
by Hydrate
skywalk wrote:Seems rather compact and easy to follow.
Is there any need to free memory or a Destructor?
Because it uses none of the complex features in Purebasic (simply uses a struct), you can destruct an object simply by using the ClearStructure() command.

It also means that copying an object is very easy. You can do it with:

Code: Select all

myRect2.Rectangle = myRect.Rectangle
Debug myRect2\width;

Re: OOP Without interfaces

Posted: Wed Jun 13, 2012 9:59 am
by STARGĂ…TE
without interfaces, you must give the own object to the procedure.
mycRect\size(mycRect, 22, 91);
if that is not complicated, it is ok.
But an interface would not need it:
mycRect\size(22, 91);

Re: OOP Without interfaces

Posted: Wed Jun 13, 2012 1:17 pm
by inc.
mycRect\size(mycRect, 22, 91);
And beside this .... its almost the way of handling objects like PB does it already
RectSize(#myRectNum, 22, 91)
So approaches where you have to provide the object pointer to methods are object based, but not object orientated.

Theres a way on 32bit compiles, but seems to be unsafe .... and maybe not supported by future PB versions:

Code: Select all

Declare.l Test_get()
Declare.s Test_set(val.l)
Prototype.l Test_get()
Prototype.s Test_set(val.l)

Structure Test
	get.Test_get
	set.Test_set
	Handle.l
EndStructure

Procedure.l Test_get()
	Protected *this.Test
	!MOV [p.p_this],Ebp
	ProcedureReturn *this\Handle
EndProcedure

Procedure.s Test_set(val.l)
	Protected *this.Test
	!MOV [p.p_this],Ebp
	*this\Handle = val
	ProcedureReturn "bla"
EndProcedure

Procedure _createTest(Size.l)
	If Size<SizeOf(Test)
	Size = SizeOf(Test)
	EndIf
	Protected *this.Test = AllocateMemory(SizeOf(Test))
	*this\get=@Test_get()
	*this\set=@Test_set()
	*this\Handle = 666
	ProcedureReturn *this
EndProcedure

Procedure.l Test()
	ProcedureReturn _createTest(0)
EndProcedure

*b.Test = Test()
Debug *b\get()
Debug *b\set(9999999)
Debug *b\Handle

Re: OOP Without interfaces

Posted: Wed Jun 13, 2012 3:25 pm
by ts-soft
inc. wrote:Theres a way on 32bit compiles, but seems to be unsafe .... and maybe not supported by future PB versions:

Code: Select all

Declare.l Test_get()
Declare.s Test_set(val.l)
Prototype.l Test_get()
Prototype.s Test_set(val.l)

Structure Test
   get.Test_get
   set.Test_set
   Handle.l
EndStructure

Procedure.l Test_get()
   Protected *this.Test
   CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
   !MOV [p.p_this],Rbp
   CompilerElse
   !MOV [p.p_this],Ebp
   CompilerEndIf
   ProcedureReturn *this\Handle
EndProcedure

Procedure.s Test_set(val.l)
   Protected *this.Test
   CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
   !MOV [p.p_this],Rbp
   CompilerElse
   !MOV [p.p_this],Ebp
   CompilerEndIf
   *this\Handle = val
   ProcedureReturn "bla"
EndProcedure

Procedure _createTest(Size.l)
   If Size<SizeOf(Test)
   Size = SizeOf(Test)
   EndIf
   Protected *this.Test = AllocateMemory(SizeOf(Test))
   *this\get=@Test_get()
   *this\set=@Test_set()
   *this\Handle = 666
   ProcedureReturn *this
EndProcedure

Procedure.l Test()
   ProcedureReturn _createTest(0)
EndProcedure

*b.Test = Test()
Debug *b\get()
Debug *b\set(9999999)
Debug *b\Handle 

Re: OOP Without interfaces

Posted: Wed Jun 13, 2012 9:52 pm
by inc.
Nice :-)

Re: OOP Without interfaces

Posted: Tue May 17, 2022 8:01 pm
by chikega
10 years later .. still a nice example that I can learn from. Thank you. :D