Pass object reference parameters
- Last Updated: October 8, 2020
- 5 minute read
- OpenEdge
- Version 13.0
- Documentation
When an application passes an object reference to a method, user-defined function, or procedure, the assignment rules can be summarized by designating the object that provides the reference as the source and the object that receives the reference as the target. The target object reference definition can be:
- The same type as the source (for example, to
acme.myObjs.CustObjfromacme.myObjs.CustObj) - A super class of the source (for example, to
acme.myObjs.Common.CommonObjfromacme.myObjs.CustObj) - An interface that the source implements (for example, to
acme.myObjs.Interfaces.IBusObjfromacme.myObjs.CustObj)
For more information on the rules for assigning object references, see Assign object references.
To pass an object between an application server and an ABL client, the class of the object must be defined on both the sending and receiving side, and the definitions of the class’s data members, properties, events, and method signatures must match exactly. The class is serialized by the sender, and the receiver uses that information to create a copy of the object.
The following restrictions apply to objects being passed as parameters (or thrown as errors) between an application server and client:
- In the case of a user-defined class, the object’s class and all of the
classes in its hierarchy must be marked as
SERIALIZABLE. For more information on marking a class asSERIALIZABLE, see Use the CLASS construct. - The content of static data members is not serialized, and the state of queries, buffers, open files, streams, and event subscriptions, for example, are not maintained.
- All of the object's data members that are defined as class-based objects
must be of a class type that is also marked
SERIALIZABLE. (This restriction does not apply to static data members that are defined as objects, because static data members are not serialized.) - Handle-based variables are serialized, but no information for reconstructing handle-based objects on the receiving side is serialized.
-
MEMPTRsassigned by an ABL application are serialized, butMEMPTRsfrom an external source (such as a DLL or shared library) are not serialized. - Statically defined temp-tables and ProDataSets in user-defined
classes are serialized, except for
REFERENCE-ONLYtables. - The
REJECTED,ERROR,ERROR-STRING, andDATA-SOURCE-MODIFIEDattributes for temp-tables in an object are maintained as part of the deserialization process. Similarly, theREJECTEDandERRORattributes for ProDataSets are maintained during serialization. - Not all built-in classes are serializable. See the
CLASSstatement entry in ABL Reference for a full list of serializable built-in classes. - .NET and ABL-extended .NET objects cannot be passed as parameters.
The following examples demonstrate the passing of object reference parameters
for INPUT, INPUT-OUTPUT, and
OUTPUT. These examples highlight code from the Main class shown previously (see Define an object reference variable or property) and related sample classes that are described and fully listed in Sample classes. Refer to these samples for
referenced class listings that are not shown in this section.
When passing an INPUT parameter, the caller
is the source of the assignment and the invoked method is the target
of the assignment. Therefore, the caller must pass an INPUT object reference
that is the same class or interface type as the defined method parameter,
that is a subclass of the class defined by method parameter, or
that is a class which implements the interface defined by the method
parameter.
If you pass a super class or interface object reference to the invoked method, the method can only use that object reference to call those methods and access data that are defined by the specified super class or interface, even if the referenced object actually represents a subclass or interface-implementing class that defines additional public methods and data. If the invoked method attempts to use this object reference to call these additional methods or access the additional data without first casting the object reference appropriately, the compiler generates an error. For more information on casting object references, see Object reference assignment and casting.
The following examples pass an INPUT parameter:
|
|
The previous example shows an acme.myObjs.CustObj instance
passed as input to the InitializeDate( ) method,
which is defined to take an acme.myObjs.Common.CommonObj (super class
of CustObj). Note that the updateTimestamp( ) method
invoked on the input object reference only exists in CommonObj.
(For a listing of this class, see Call methods from inside a class hierarchy where they are defined.) This method can be invoked
on any object that is a subclass of CommonObj.
For more information on acme.myObjs.Common.CommonObj,
see Sample classes.
When you pass an object reference data element as an INPUT-OUTPUT parameter,
it must have the same class or interface type as the corresponding
parameter definition. Because the object is being passed in both
directions, its type must match the parameter definition exactly.
The following examples pass an INPUT-OUTPUT parameter:
|
|
The previous example shows an acme.myObjs.CustObj instance
passed as an INPUT-OUTPUT parameter to the ListNames( ) method
in acme.myObjs.Common.HelperClass. In this case, the
type on both sides (the passed object reference and the parameter
definition) have to be exactly the same, in this case CustObj.
The ListNames( ) method uses the input
object reference and stores the value in its PRIVATE data
member, rCustObj.
When passing an OUTPUT parameter, the caller
is the target of the assignment and the invoked method is the source
of the assignment. Therefore, the caller must pass a parameter that
is the same class or interface type as the defined method parameter,
that is a super class of the class defined by method parameter,
or that is an interface which is implemented by the class defined
by the method parameter.
Once again, if the caller passes a super class or interface object
reference data element for OUTPUT, the caller can
only use that object reference to invoke those methods and access
data that are defined by the specified super class or interface,
even if the referenced object actually represents a subclass or
interface-implementing class that defines additional public methods
and data. If the caller attempts to use this object reference to
call these additional methods or access the additional data without
first casting the object reference appropriately, the compiler generates
an error. For more information on casting object references, see
Use the CAST function.
The following examples pass an OUTPUT parameter:
|
|
In the previous example, ReportOutput( ) defines
an OUTPUT parameter defined as an object reference
to the acme.myObjs.Interfaces.IBusObj interface.
Through the OUTPUT parameter, this method in acme.myObjs.Common.HelperClass returns
a PRIVATE object reference to an acme.myObjs.CustObj,
which is initially set to a CustObj instance by
the ListNames( ) method of the class.
This works because the CustObj class implements
the IBusObj interface. Therefore, ReportOutput( ) can
return any object that implements IBusObj. Note
that after ReportOutput( ) returns in ObjectInfo( ),
the logObj( ) method is called on the OUTPUT object
reference. This method is declared in the IBusObj interface
and implemented in CustObj. It would be invalid
to invoke a method on the OUTPUT object reference
that is not declared in this interface, even though the original CustObj instance
passed as an IBusObj defines additional PUBLIC methods.