Classes
- Last Updated: July 25, 2024
- 4 minute read
- OpenEdge
- Version 12.8
- Documentation
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).
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.
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 object-oriented
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.
OpenEdge supports both the .NET Framework runtime and .NET core runtime, simply known as ".NET".
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 names 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 (.NET Framework only) 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 configurable directories or for .NET Framework, a standard location defined by .NET known as the Global Assembly Cache (GAC). For .NET, there is no GAC, but there is a "host assembly store" which includes a set of assemblies that are installed with the .NET runtime. OpenEdge supports options for specifying the location of other assemblies you access from your application.
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.