|
| Previous: 2.9.3 Objects | TOC | Index | Back | Next: 2.9.5 Methods and Messages |
In order to create an instance of a class A inside of a class B, B must require A. B is also said to depend on A. The most simple scenario contains two classes which are defined inside of the same file:
CLASS a() ! definitions of A END CLASS b(a) OBJECT xa[a]; END
Since B instantiates A, it must require A. A class is required by including its name in the dependency list of the class header of the dependent class. Requiring a class has two effects:
Things get a little more complex, if the dependent class and the required class are located in different files. Since class names are contained in the global scope, they are lost as soon as the compiler has finished the translation of the file they are contained in. Hence the required class would be unknown when the compiler translates the file containing the depedent class. To allow classes to be located in different files, an additional level above the global scope is added. It is called the public scope and it persists even when the compiler finishes.
To add a class to the public scope, two steps are necessary. First, the file must get a module header. This is done by adding a MODULE statement, which has the following general form:
MODULE module_name (required, ...);
The module name specified in the module header must be the same as the actual name of the file containing the module (but not including the .t suffix). If, for example, the class A is located in a file named tools.t, the module header would look like this:
MODULE tools();
The parentheses after the module name serve the same purpose as in class definitions: they delimit a dependency list. This list may be ignored for now. The module header allows the compiler to locate the definition of a class, even if multiple classes are contained in a single file. (If files were named after classes, only a single class could be included per file.)
The second step required to export a class to the public level is to prefix its class header with the keyword PUBLIC:
PUBLIC CLASS a()
The following example shows the contents of two files file_a (containing the required class A) and file_b (containing the dependent class B). When compiling file_a, A is exported to the public level. File_a must be compiled before file_b. When compiling file_b, A is imported from the public level when it is required by B.
MODULE file_a(); MODULE file_b(); PUBLIC CLASS a() CLASS b(a) ! definitions OBJECT xa[a]; END END
Another purpose of the MODULE statement is to provide an interface between the procedural and the object oriented parts of T3X. If only classes could require classes, it would be impossible to instantiate a class inside of a T3X program, since the main program is procedural. To instantiate a class in a procedural program, it is added to the dependency list of the module wishing to instantiate the class. It does not matter whether the required class is a public class contained in a different module or a 'private' class contained in the same module. In the latter case, however, the MODULE statement must be located after the class definition. The next example shows a procedural program sending a message to a class.
CLASS A(util)
OBJECT u[util];
PUBLIC m() u.printf("A: received m.\n", 0);
END
MODULE main(A);
DO OBJECT xa[A];
xa.m();
END
| Previous: 2.9.3 Objects | TOC | Index | Back | Next: 2.9.5 Methods and Messages |