Try OpenEdge Now
skip to main content
Object-oriented Programming
Getting Started with Classes, Interfaces, and Objects : Defining classes : Defining classes based on other classes
 

Defining classes based on other classes

A user-defined class (defined using the CLASS statement) can extend another class by inheriting it. In ABL, a class can inherit from at most one other class, which in turn can inherit from another class. This single inheritance model makes the non-PRIVATE data members, properties, methods, and events of the super class appear as if they are part of the class being defined. If a class is marked as FINAL, it cannot be inherited (used as a super class for another class). The different classes that make up a class hierarchy are stored in separate class files, both in their source code form and their r-code form. However, at both compile time and run time, all the parts of a class hierarchy are treated as a single unit, and must all run in the same ABL session. Thus, an object is an instantiation of a class hierarchy, not simply the class that is instantiated. This object can also represent (have the class type of) any class in that hierarchy, and can be referenced as any one of these classes. For more information on class hierarchies and inheritance, see Class hierarchies and inheritance.
A class can also be abstract. An abstract class is just like a non-abstract class except for three features:
*It must be defined with the ABSTRACT option.
*It cannot be instantiated, but must be inherited by a derived class; therefore, it cannot be marked FINAL.
*In addition to being able to implement any other class member or element, it can declare abstract properties, methods, and events, each of which must be implemented by a derived class. The implementing class must be the first derived non-abstract class, unless a derived abstract class has already implemented the abstract member.
An abstract property, method, or event is declared with a prototype that defines only type information for the specified class member. No storage or code implementation is associated with an abstract member declaration. The abstract prototype declaration simply creates the requirement that a class member of the specified type must be implemented in a derived class. Otherwise, you can access and manipulate abstract members (according to their type) in a manner similar to implemented members, because an implementation is guaranteed to exist at run time.
A user-defined class can also implement methods, properties, and events whose prototypes are declared by an interface (defined in the INTERFACE statement). An interface is not a class in itself, but similar to a class, it does represent an object type (interface type). An interface type specifies the prototypes of properties, methods, and events for classes to implement, similar to abstract members of a class type. Thus, an interface does not specify any method, property, or event implementations itself, but it only provides a particular set of method, property, or event prototypes that different classes can implement as required. In fact, it is a compiler error for a class not to provide an implementation for every method, property, or event prototype specified in an interface that it implements. An implementing class can meet this requirement by inheriting method, property, or event implementations from a super class, as well as by defining its own method, property, or event implementations.
Again, although an interface is not a class, it does specify the type of an object. Thus, an object instantiated from a class that implements an interface can be referenced as an instance of that interface type as well as an instance of its class type. If a class implements several interfaces, an object instantiated from that class can also be referenced as an instance of each interface type implemented by that class, including any inherited interface types. However, note that you cannot instantiate an interface the way you can instantiate a non-abstract class. You can only reference a class that you have already instantiated as an instance of an interface type that the class implements.
Note that while similar in application, the key difference between interface members and abstract members is that abstract members define prototypes in an abstract class that must be inherited and implemented by a derived class. So, abstract members participate fully in any class hierarchy where they are defined, and can be referenced at the same points in a class hierarchy as any other member. Interface members can only be referenced through the interface type where they are defined or through a class that implements these interface members.
Note: Both abstract classes and interfaces can be used to guarantee the API for applications that implement a delegation model. For more information, see Using delegation with classes.