One of the most useful aspects of the OOPS programming is the possibility to define functions (methods) and that runs inside the context of the object instance. The object instance will contain also private data. In Xbase++ we have instance variables. In C++ the instance data is stored in the same disposition as a structure, we also can create a C++ class that inherits directly from a structure.
Ot4xb use inheritances of the gwst class to manage structures, so it's possible to inherit from a gwst class to add methods that extend it's functionality.
See the following example:
// Tutor06.prg
BEGIN STRUCTURE _RECT_
MEMBER LONG left
MEMBER LONG top
MEMBER LONG right
MEMBER LONG bottom
END STRUCTURE
First we have defined a base gwst class to hold the data of our structure, so now we only need to create a new class using inheritance from our defined base class.
CLASS RECT FROM _RECT_
EXPORTED:
At least the first inheritance of a gwst subclass must have defined the method initClass(). Int his case, we not need to do any class initialization so we will define a dummy initClass() method.
INLINE CLASS METHOD initclass() ; return Self
Now we can add some methods to extend the functionality of our structure class
INLINE ACCESS ASSIGN METHOD width( v )
if PCount() > 0
::right := ::left + v
return NIL
end
return ::right - ::left
In this case we have defined 2 extra pseudo-properties to manipulate the rectangle using the width and height components.
INLINE ACCESS ASSIGN METHOD height( v )
if PCount() > 0
::bottom := ::top + v
return NIL
end
return ::bottom - ::top
ENDCLASS
Now we can manipulate our RECT class using with the new extended functionality
proc main()
local oRect := RECT():New()
@user32:GetWindowRect( SetAppWindow():GetHWnd() , oRect)
? "Width : " , oRect:width
? "Height: " , oRect:height
inkey(0)
return
Gwst structure definition commands are built using the ot4xb TXbClass() and some wrapper commands around the TXbClass() methods. For this reason it's so easy add inline methods and properties in the same step we are defining our structure.
The next example have the same functionality implemented in Tut06.prg but in a single step, without the need to define a base class for later derivation.
// Tut07.prg
BEGIN STRUCTURE RECT
MEMBER LONG left
MEMBER LONG top
MEMBER LONG right
MEMBER LONG bottom
// --------------------
DYNAMIC PROPERTY width READ ( ::right - ::left );
WRITE ( ::right := ::left + v)
// --------------------
DYNAMIC PROPERTY height READ ( ::bottom - ::top );
WRITE ( ::bottom := ::top + v)
// --------------------
END STRUCTURE
The choice criteria is simple, if the added functionality is so complex is better to use standard subclassing to add the new methods and properties, if the added functionality is something simple like in the case of Tut07.prg, we can insert our methods within the structure declaration.