Element descriptions for this syntax diagram follow:
object-reference
The name of a data element (for example, variable, writable property, or parameter) appropriately defined as a class or interface type.
This object-reference must be defined as one of the following types:
The same class as the class type specified by class-type-name or expression
A super class of the class type specified by class-type-name or expression
An interface implemented by the class type specified by class-type-name or expression
Note: If object-reference is a temp-table field, its object type name can only be Progress.Lang.Object, the type name of the ABL root class. For more information on the ABL root class, see Using the root class: Progress.Lang.Object.
NEW class-type-name
Where class-type-name is the type name of the class to instantiate; it cannot be an interface type name. This can be the fully qualified type name or the unqualified class name, depending on the presence of an appropriate USING statement in the class or procedure file. For more information on forming type names for class-based objects, see Defining and referencing object type names. For more information on the USING statement, see Referencing an object type name without its package.
DYNAMIC-NEW expression
Where expression is a character expression that evaluates, at run time, to the fully-qualified type name of the class to instantiate; it cannot be an interface type name. For more information on forming type names for class-based objects, see Defining and referencing object type names. The value of expression is not affected by any USING statements because USING statements only operate with a compile-time type name, as you provide for the NEW statement. The DYNAMIC-NEW statement is useful for OERA-compliant applications, where you want to instantiate a class whose type (specified in expression) is passed as a parameter to a method. Such a method allows you to instantiate one of a set of classes without the need to perform an IF or CASE statement test for the identity of the class type. This works especially well when the possible class types specified by expression all implement the same set of interfaces.
[parameter[ , parameter]...]
The parameters, if any, passed to a PROTECTED or PUBLIC constructor defined by the class-type-name or expression class. If the class defines more than one PROTECTED or PUBLIC constructor, the constructors are overloaded and these parameters identify the constructor to use for instantiating the class. For DYNAMIC-NEW, the constructors for all possible class types specified by expression must all take the same number of parameters defined with compatible data types and modes. For any one class instantiated by DYNAMIC-NEW, its instance constructors can be overloaded by the number of parameters, by the parameter data types or by the modes.
For more information on the syntax of parameter, see the Parameter passing syntax reference entry in OpenEdge Development: ABL Reference. For more information on passing parameters to overloaded constructors, see Calling an overloaded method or constructor.
Whenever you create an instance of a class, the specified constructor of the instantiated class, as well as the specified constructors of any super classes in its class hierarchy, are run. The instantiated object also gets its own copy of PROTECTED and PUBLIC data members and properties defined by all classes in its class hierarchy. That is, all instances of a class share a single set of methods defined for that class, but each instance has its own data not shared with any of the others. Thus, just as with persistent procedures, each instance of a class is a separate entity with its own instance data. For more information on how ABL constructs a class-based object, see Constructingan object.
This example, from the Main class described previously creates instances of two sample classes in its constructor:
USING acme.myObjs.*.
USING acme.myObjs.Common.*.
USING acme.myObjs.Interfaces.*.
CLASS Main:
DEFINE PRIVATE VARIABLE rCustObj AS CLASS CustObj NO-UNDO.
DEFINE PRIVATE VARIABLE rHelperClass AS CLASS HelperClass NO-UNDO.
...
CONSTRUCTOR PUBLIC Main( ):
ASSIGN
/* Create an instance of the HelperClass class */
rHelperClass = NEW HelperClass ( )
/* Create an instance of the CustObj class */
rCustObj = NEW CustObj ( ) cOutFile = "Customers.out".
/* Subscribe OutputGenerated event handler for CustObj */
rCustObj:OutputGenerated:Subscribe(OutputGenerated_CustObjHandler).
END CONSTRUCTOR.
...
END CLASS.
You can also use the NEW function in any expression outside of a NEW statement, without assigning the object reference, as long as the expression is appropriate for referencing the instantiated class. An example is when accessing a property on the object reference returned by the NEW function that returns a value that is data-type compatible with the expression.
For example, if you have a class that takes a default constructor, Deposit, and this class defines a DECIMAL property, Maximum, you can both instantiate the class and display the property value directly on the object reference returned by the NEW function in the MESSAGE statement that follows:
MESSAGE "The maximum deposit is " (NEW Deposit( )):Maximum VIEW-AS ALERT-BOX.
This Maximum property reference represents a chained reference on the result of the NEW function. Note that in order to reference a member of a class by chaining on the instantiating NEW function, you must bracket the function reference with parentheses and follow the closing parenthesis with the member reference. Note also that when you do not assign the object reference from a class instantiation, as in this example, ABL automatically deletes the instantiated class at some point after it is no longer needed in the expression.