Language Elements and Reference:xpplrm

Operations using objects Foundation

This chapter can give a only brief overview of the most important operations for objects. If you have not yet programmed with objects or you know only a little about them, this chapter should be skipped until you have read the next chapter, "Object-oriented programming". Detailed information on different classes and objects can be found in the reference documentation.

The operators that can be used with the "object" data type are, with one exception, the same as for the two other complex data types "array" and "code block". They are listed again in the following table:

Operators for objects
Operator Description
: Sends message to object
:: Sends message to the object self
== Tests whether two objects are identical
= Comparison: equal
!= <> # Comparison: not equal
= Assignment
:= Inline assignment

By far the most important operator for objects is the send operator : (the colon) which sends messages to objects. Messages contain the names of member variables to be accessed or identifiers for methods to be executed.

oGet := Get():new()                // create Get object 
oGet:row := 3                      // assign value to member variable 
oGet:display()                     // execute method 

The characters :: represent an abbreviation for self: and are a special form of the send operator. They send a message to the object which is referenced in the variable self. This variable implicitly exists within methods as a LOCAL variable and always references the object currently executing the method.

Along with the operators specified in the table, all other operators described previously can be applied to member variables of objects. The available operators depend on the data type of the value contained in the member variable. Examples:

oGet:row ++                        // increment operator 
oGet:row -= 6                      // combined inline assignment 
IF oGet:row > 20                   // greater than 
   oGet:row = 0                    // simple assignment 
ENDIF 

Comparison of two objects

Objects, like arrays and code blocks, are referenced in variables. The same rules that are valid for comparing the other complex data types are valid for comparing two objects. The exact equals operator == returns the value .T. (true) only when the two variables reference the same object. The simple comparison "equal" and "not equal" operators require the value NIL as the second operand:

oGet1 := Get():new() 
oGet2 := Get():new() 
oGet3 := oGet1 

? oGet1 == oGet2                   // result: .F. 
? oGet1 == oGet3                   // result: .T. 

? oGet1 = NIL                      // result: .F. 
? oGet2 <> NIL                     // result: .T. 

In the example, the two variables oGet1 and oGet3 contain references to the same object. The variables oGet1 and oGet2contain references to objects of the same class (Get class), but the references are different. Correspondingly the result of the exact equals operator is .F. (false).

The functions available for the "object" data type include the group of class functions which have the class object of a class as a return value, as well as some functions which exist for compatibility. They are listed in the following table:

Functions for objects
Function Description
ErrorNew() Create Error object *)
GetNew() Create Get object *)
TBrowseDb() Create TBrowse object with predefined code blocks for files *)
TBrowseNew() Create TBrowse object *)
TBColumnNew() Create TBColumn object *)
DataRef() Class function of the DataRef class
Error() Class function of the Error class
Get() Class function of the Get class
TBrowse() Class function of the TBrowse class
TBColumn() Class function of the TBColumn class
Thread() Class function of the Thread class
Xbp...() Class functions for Xbase Parts
  1. These functions exist only for compatibility

Class functions are called using the name of the class followed by parentheses. They always return the class object. The functions whose function names include NEW create objects of a class and are provided for language compatibility with CA Clipper. The compatibility functions should no longer be used with Xbase++. Instead, objects should be created using the class object. The method :new(), exists in each class and is executed from the class object (class method).

All class functions which begin with the prefix "Xbp" return a class object from Xbase Parts. Xbase Parts provide objects for dialog components that are tuned especially for the operating system (Xbase Parts are described further in the chapter "User interfaces and dialog concepts").

The Xbase++ object model contains five methods used in all classes (and redefined classes). These identifiers (or names) are reserved. Each of these methods serve specific purposes needed in all classes. They are presented in the next table:

Methods for all classes (reserved methods)
Method Description
:new() Create object (instantiate class object)
:init() Initialize object (instance object) *)
:initClass() Initialize class (class object) *)
:className() Determine name of the class to which an object belongs
:classObject() Determine class object of an instance object
:isDerivedFrom() Determine if an object is derived from a particular class
  1. This method must be redeclared, if necessary, in each class

With the exception of the method :init(), all reserved methods are executed only by a class object (the return value of the class function). The method :new() creates new instances (objects) of a class. If it is declared within the class, the method :init() is automatically executed by an instance object immediately after it has been created by the class object. The same parameters that :new()received are passed on to the method :init(). The instance variables of the new object are generally initialized within :init().

The method :initClass() is similar to :init() and initializes the class object. When :initClass() is declared as a class method (CLASS METHOD), this method is executed as soon as the class object in the class function has been created. The parameters that are passed to the class function are also passed to :initClass().

The two methods :init() and :initClass() should be redeclared within each class declaration to initialize the member variables of the class object and instances (when a class has no class variables,:initClass() does not need to be redeclared).

The two methods :className() and :classObject() are needed to determine information about an object. The method :className()returns a character string containing the name of the class to which an object belongs. :classObject() returns the class object of an instance object. This method is needed to determined whether two objects belong to the same class:

objectA := Get():new() 
objectB := TBrowse():new() 
objectC := Get():new() 

? objectA:classObject() == objectB:classObject() // result: .F. 
? objectB:className()                            // result: TBrowse 

? objectA:classObject() == objectC:classObject() // result: .T. 
? objectA:className()                            // result: Get 

? objectA == objectC                             // result: .F. 

:className() and :classObject() are class methods. The example demonstrates that instances of a class redirect the messages that call class methods to the class object. When the message for a class method is sent to an instance object, this message is redirected to the class object because each instance object knows "its" class object.

Feedback

If you see anything in the documentation that is not correct, does not match your experience with the particular feature or requires further clarification, please use this form to report a documentation issue.