Beginning with OpenEdge® Release 10.1, ABL includes support for classes. Classes allow an ABL application to be built from built-in classes, as well as user-defined class-based objects that can be defined and organized for use by an application at compile time. Class-based objects are defined and managed using standard features of object-oriented programming available in ABL, and are similar to other programming languages such as Java. Procedure-based and class-based objects can coexist in a single application.
Object-oriented programming support in ABL extends the language to provide a cohesive and standard object-oriented programming model, while continuing to support the programming model available in previous releases of OpenEdge. That is, ABL provides support for programming with classes in addition to its support for programming with procedures with full interoperability between the two. This object-oriented language support is a natural basis for writing applications that conform to the OpenEdge Reference Architecture (OERA) introduced with OpenEdge Release 10.
You define a class using the CLASS statement and define its members within the class block terminated by the END CLASS statement. A new instance of a class is created using the NEW function. This is comparable to running a persistent procedure using the RUN statement, and returning a handle to the procedure with the SET option.
In OpenEdge releases prior to Release 10.1A, ABL persistent procedures allow you to create and manage objects in which most of the relationships between them are created and managed at run time. ABL classes, on the other hand, contain relationships that you create at compile time. Unlike a persistent procedure, a class defines a well-structured, strong type (data type) that ABL recognizes and verifies at compile time and that can be realized as an object at run time. A persistent procedure is weakly typed and therefore can only be verified at run time. The data type of a class is defined by its members. That is, as long as the interface defined by the members of a class does not change, the data type of the class remains the same no matter how much you change its implementation. This has significance for determining when you have to recompile a given class or procedure when a class upon which it depends changes.
Class members are themselves strongly typed elements that provide data and behavior for the class, similar to the variables, handle-based objects, internal procedures, and user-defined functions of a persistent procedure. Again, as strongly typed elements, the members of a class are verified at compile time, while the similar elements of a procedure can only be verified at run time. In addition, classes are built in strict hierarchies, where any given user-defined class inherits strongly-typed members from another class as well as defining members of its own, all of which can be inherited by yet another user-defined class. This strong typing of classes and their inheritance relationships allows for robust error checking at compile time, when an application is in the development cycle, and long before it is available to end users.
In terms of the static DEFINE versus dynamic CREATE ABL perspective, all OO programming in ABL is dynamic. You instantiate objects explicitly at run time and you set their properties much as you do with the ABL CREATE statement.
ABL and .NET organize their class-based type hierarchies using different mechanisms. ABL organizes user-defined types into packages, which are logical pathnames that correspond to physical directory paths relative to PROPATH. It then stores the types in class definition (.cls) files that reside in the corresponding directories.
On the other hand, .NET organizes its object types into namespaces, which are logical pathnames that are defined along with the object types associated with them. .NET namespaces are completely logically defined and have no correspondence to physical storage of any kind. Instead, .NET stores object type definitions, along with their defined namespaces, in assembly files. An assembly can be a Windows dynamic link library (.dll) or executable (.exe) file that is formatted to store one or more types associated with their individual namespaces. These assemblies are then stored in designated locations, which can include locally configureable directories or a standard location defined by .NET known as the Global Assembly Cache (GAC). OpenEdge supports options for specifying the location of the assemblies you access as part of the GUI for .NET.
Thus, a .NET namespace is analogous to an ABL package in that it provides a means to organize and uniquely identify types. But instead of being associated with an actual directory structure where the type definition is stored, a namespace is a logical construct that is associated with each type that is stored in an assembly.
Both .NET namespaces and ABL packages are hierarchical. The representation of each type of hierarchy in ABL uses the same dot-separated notation, whether it is logical for namespaces or physical directory-based for ABL classes.
Note that this and other OpenEdge product documentation does not replace and, in fact, depends on both Microsoft and third-party vendor documentation for understanding the .NET classes that vendors provide. OpenEdge supplies code samples that provide examples of using classes. These code samples can be found on the self-extracting Documentation and Samples file available on the OpenEdge download page of the Progress Software Download Center under the following relative directory path: