The CLASS construct represents all of the statements that can comprise a class definition. The class definition specifies a main block, starting with a CLASS statement that identifies the class. After any USING statements, the first compilable line in a class definition file that defines a class must be this CLASS statement. The last compilable line in a class definition must be the END CLASS statement, which terminates the main block of the class.
Note: The CLASS statement is only valid in a file with the .cls extension.
This is the syntax for defining a class.
Syntax
CLASS class-type-name[ INHERITS super-type-name] [ IMPLEMENTS interface-type-name[ , interface-type-name]...] [ USE-WIDGET-POOL ][ ABSTRACT | FINAL ] [ SERIALIZABLE ] :
[data-member...] [property...] [constructor...] [method...] [event...] [destructor] [class-scoped-handle-object...] [trigger...] [udf-prototype...] END [ CLASS ] .
Element descriptions for this syntax diagram follow:
class-type-name
The object type name for the class definition, specified using the following syntax:
[ " ][package.]class-name [ " ]
package
A period-separated list of string components that comprise a package name that, along with class-name, uniquely identifies the defined class among all accessible classes and interfaces in your application environment.
Note that you cannot specify Progress as the first component of the package name for any ABL user-defined class. For example, Progress.Inventory is an invalid package name for a user-defined class and results in a compiler error.
class-name
The class name, which must match the filename of the class file containing the class definition.
For a class definition, if the class is defined in a package, you must specify package, even if the class definition file contains a USING statement that specifies the fully qualified object type name for the class or its package. For more information, see Referencing an object type name without its package.
INHERITS super-type-name
The immediate super class that this class inherits, where super-type-name is the class type name of this super class. Logically, the super class's non-private members can be thought of as part of the current class definition. The super class can be a class that in turn inherits from another class. When a class is defined using the INHERITS phrase, the class being defined is referred to as a subclass. All of the super classes of this subclass constitute the class hierarchy for this class definition.
The syntax for super-type-name is the same as for class-type-name. However, if a USING statement specifies a fully qualified super-type-name or its package, you can specify the super class using its unqualified class name. For more information, see Referencing an object type name without its package. Based on this information, ABL must be able to locate each specified super class definition file (either the source file or the r-code file) in order to compile or run the user-defined class. Also, the specified super class cannot be defined as FINAL.
If you do not specify this option, the class inherits directly from the ABL root class, Progress.Lang.Object. For more information on this built-in class, see Using the root class: Progress.Lang.Object.
One or more interfaces that this class implements. The current class hierarchy must implement all the properties, methods, and events declared in each interface specified as interface-type-name, including all properties, methods, or events inherited from super interfaces.
The syntax for interface-type-name is the same as for class-type-name. However, if a USING statement specifies a fully qualified interface-type-name or its package, you can specify the interface using its unqualified interface name. For more information, see Referencing an object type name without its package. Based on this information, ABL must be able to locate the specified interface class file (either the source file or the r-code file) in order to compile or run this user-defined class.
USE-WIDGET-POOL
Creates one or two unnamed widget pools, one that is scoped to the current class instance for handle-based objects associated with instance members of the class, and a separate unnamed widget pool scoped to the class type for handle-based objects associated with static members of the class. The specified instance unnamed pool serves as the default widget pool for all dynamic widgets and other dynamic handle-based objects that the class instance creates, unless there is a more locally-scoped unnamed widget pool in effect when the handle-based object is created. The AVM puts a dynamic handle-based object into the current default widget pool unless the statement that creates it uses the IN-WIDGET-POOL option.
The AVM deletes the associated class unnamed widget-pool (specified using this option) when each instance of the class is deleted. The specified static unnamed pool serves as the default widget pool for all handle-based objects created in the context of any static members of the class and persists for the duration of the session. For more information on static class members, see Usingstatic members of a class.
If a class definition does not include the USE-WIDGET-POOL option, the AVM follows the same rule for choosing the default widget pool as in procedures:
If one or more locally-scoped unnamed widget pools have been created, the AVM uses the most locally-scoped unnamed widget pool.
If no locally-scoped unnamed widget pools have been created, the AVM uses the session unnamed widget pool.
For more information on using widget pools with classes, see Using widgetpools.
ABSTRACT
If specified, this class is defined as abstract, allowing it to define abstract class members (as well as non-abstract class members), including properties, methods, and events. You cannot instantiate an abstract class, and whether or not it defines abstract members, it must be inherited by another class; therefore, an abstract class cannot be defined with the FINAL option.
The first non-abstract subclass that inherits from this abstract class must also implement any abstract members that are inherited in its class hierarchy. An implemented member is any inherited abstract member that is defined with the OVERRIDE option and without the ABSTRACT option. For more information, see Definingproperties within a class, Definingmethods within a class, and Definingevents within a class.
FINAL
If specified, this class cannot be inherited. That is, it cannot be specified as a super class for the INHERITS option of another class definition.
SERIALIZABLE
Indicates instances of the class can be:
passed between an AppServer and a remote ABL client
serialized to a binary or JSON stream
All classes in the hierarchy must be marked as SERIALIZABLE, so using this option on a class that inherits from a non-serializable class will raise a compile-time error. The class types of any data members that are themselves class-based objects must also be SERIALIZABLE. The SERIALIZABLE option cannot be used with ABL-extended .NET classes.
A data member definition. A class can define zero or more data members of the class. For more information, see Defining data members within a class.
property
A property definition. A class can define zero or more properties of the class. For more information, see Definingproperties within a class.
method
A method definition. A class can define zero or more methods of the class. For more information, see Definingmethods within a class.
event
A class event definition. A class can define zero or more events of the class. For more information, see Definingevents within a class.
constructor
A constructor definition. A class can define zero or more constructors for the class. For more information, see Definingclass constructors.
destructor
A destructor definition. A class can define one destructor for the class. For more information, see Definingthe class destructor.
class-scoped-handle-object
A static ABL widget, stream, or work-table definition. A class can define zero or more of these static handle-based objects to provide private resources for a class definition. For more information, see Defining class-scoped handle-based objects.
trigger
A trigger definition. A class can define zero or more ON statements that specify triggers for a class. Each ON statement specifies a response to a specific set of handle-based object events, mostly from interactions with ABL widgets. For more information, see Using handle-based object events in classes.
udf-prototype
A user-defined function prototype. If you invoke a user-defined function in a procedure object handle from within the method of a class, you must provide the function prototype and a handle to the running external procedure where the user-defined function is defined. You must also provide the function prototype with the IN SUPER option if the user-defined function is defined in a super procedure for the session. This is the same prototype and handle reference that you must provide in any procedure that references an external user-defined function. For more information, see the reference entry for the FUNCTION statement in OpenEdge Development: ABL Reference.
You can terminate a CLASS statement with either a period (.) or a colon (:). The data-member, property, constructor, method, destructor, trigger, and udf-prototype specifications can appear in any order.
The following sample shows an abstract class definition:
CLASS acme.myObjs.Common.CommonObj ABSTRACT: ...
END CLASS.
The following sample shows a class definition that inherits from the previous class, its super class:
USING acme.myObjs.Common.*. CLASS acme.myObjs.CustObj INHERITS CommonObj: ...
END CLASS.
Note the USING statement that allows an unqualified reference to the CommonObj class name to specify its class type. However, the class type specified for the class definition must be fully qualified with its package.
The following sections, and other sections in this book, make reference to and build on this sample class definition (referred to as "the sample class"). This class and other associated class and interface definitions in this and other chapters (referred to as "a sample class" or "a sample interface") sometimes represent partial or modified implementations of the sample classes that are fully presented in a later chapter of this manual. For more information, see Comparing constructs in classes and procedures.