Chapter 3 The Application Description Language
ADL
description of an AM2 application consists of class definitions and initialized instances of those classes. Most class definitions include object members that are instances of other classes. The initialization of these instances is what gives an AM2 application its particularity. It is whatmakes one interface screen different from another and what distinguishes a particular interface button from the next. The ADL provides several mechanisms for initializing object instances. Each of these is optional, and each is applied successively. The initial state of an object is the result of these cumulative and possibly overlapping initializations. The complete initialization sequence for an ADL object is as follows.
In this case, aInstance and bInstance are instances of the class MyClass. We
initialize aInstance in the following steps:
Constructor methods require comment since their definition uses a special syntax. In general, bases need not know anything about their derived instances. But there are circumstances where this is not the case. For instance, windowing systems generally refuse to create widgets without knowing the parent widget. In the ADL, widget containment is implemented as class membership. That is, a manager widget contains its child widgets as members. If those child widgets are subclasses of the base wrapped widgets, then the initialization of the subclassed child widgets must inform the wrapped bases of their parent during processing of the constructors.
As an example, consider a specialization of the base button class, XFbutton, called ExitButton. ExitButton has special behavior, background color and label. If we go to create a manager that contains an exit button, then the constructor for this ExitButton must somehow inform the base XFbutton of its manager parent. The ADL distinguishes constructor method definitions in order to add the mechanism to make this possible. Figure 3.48 illustrates this.
upon selector [: type1 arg1, ... , typen argn] [init { CtorMessage1 => base1, ... , CtorMessagen => basen }] |
Constructor definitions start with the keyword upon instead of on. The constructor body can be preceded by an optional init block that specifies constructor calls for direct bases. The constructor messages in this block must correspond to special constructors defined in the bases. The constructor messages in the init block are evaluated in the scope of the constructor execution so they have access to the constructor arguments.
The SetAttributes (see Figure 3.37, "Sample SetAttributes Call" page 39) method alleviates a scoping problem for constructors and initializor blocks. Initializor blocks provide the application developer far greater flexibility in initializing object members than constructors, but because they have object method scope, they cannot refer to variable values from the scope in which the object is being initialized. A special constructor that takes an attribute/value list as its sole argument can import an arbitrary set of values from the initializing scope and use them to initialize the object, thus circumventing the fixed argument list of the special constructor and the restricted scope of the initializor block.
Generated with Harlequin WebMaker