Documentation
Getting Started
New Features
Component Guide
Programming
    Language Guide
    Language Ref.
       General Design
       Lexical Structure
       Expressions
       Objects
       Methods
       Classes
       heitml Tags
       heitml Functions
       Database Access
       Global Variables
       Form Fields
       Server Variables
       Sessions
       heitml Syntax
    Component Ref.
    Class Library
    User Components
    Tryout Form
    Tutorial
    heitml 1
User Guide
Registration
Frame
    

Classes

Besides the two predefined classes Object and Page, new classes can be defined using the def, defenv, or defclass tags with inherit. Each heitml class has a name and methods. Method definitions can be placed inside class definition. Methods inside a class definition directly belong to that class. They are called nested methods in contrast to the top level methods.

Classes can have a single special method called constructor. The constructor has the same name as the class and it is defined implicitly when the def or defenv tag is used to define the class.

Object Creation

An object of a particular class can be created by calling the constructor method of that class. The constructor method has the same name as the class. For top level classes (classes defined outside any other class definition) the same visibility, calling, and parameter passing rules apply as for top level methods. In addition to a normal method call, a constructor call creates an object of the current class. The constructor can access the object by using the this key word.

Example:

heitml input:
<def myclass><inherit object>
<let this.test = "hello">
<? this>
</def>

<myclass>
resulting output:

myclass(test="hello")

in contrast to that a normal method call does not create a new object but uses the default page object, since top level methods automatically belong to the predefined Page class

Example:

heitml input:
<def mymethod>
<let this.test = "hello">
<? this>
</def>

<mymethod>
resulting output:

page(test="hello")

The newly create object can be returned as a function result, as an output parameter, or stored in a global variable.

Inheritance

The tag lists the set of direct superclasses of the defined class. The defined class inherits the methods of all its superclasses. In heitml, there is no inheritance of attributes, since objects are completely dynamic.

Inheritance means that all methods that belong (directly or indirectly) to the superclasses (indirectly) belong to the defined class unless they are explicitly overwritten. A method can be overwritten by a method with the same name, in the defined class or in a superclass later in the list of superclasses.

Class based Method Call

Nested methods that (directly or indirectly through inheritance) belong to a class are visible within this class, i.e. in all methods defined in this class (including the constructor). Directly defined methods are visible after the class definition.

Nested methods are only visible inside classes that define or inherit them and inside environment classes.

Visible nested methods can be called using the tag syntax, just as top level methods. Calling a method implicitly passes the current object (i.e. the object that can be accessed by this) to the called method.

Example:

heitml input:
<def myclass2 a; inherit object; 
   def printme; ? this; /def;
   
   this.me="Hello"+a;
   printme;
 /def>
 
<myclass2 " World">
resulting output:

myclass2(me="Hello World")

A call always calls the method of the class of the current object with the given name. This feature is known as virtual method call. In fact, not always the same method is called, but the method called depends on class of the current object.

Example:

heitml input:
<def mysuper; inherit object;
    def printme; ? this; /def;
  
    def dowork; 
       this.me=this.me+" world"; 
       printme;
    /def;
  
    this.me="Hello "; dowork;
 /def;

 def myclass3; inherit mysuper;
    def printme> This is myclass: <? this.me> </def;
	
    this.me="Test "; dowork;
 /def>

<mysuper> <p>
<myclass3>
resulting output:

mysuper(me="Hello world")

This is myclass: Test world

Please note, that the myclass3 object inherits the dowork method of the mysuper class. The dowork method in turn calls printme. Since printme has been overwritten, the printme method of myclass3 is called when the current object is of class myclass3.

Object Method Call

If x is an object and m a method then x.m() calls the method m of the class x belongs to. This feature is known as virtual method call since the method to be called is not fixed but is variable depending on what class the object x belongs to.

Syntax:
Expr::= Expr . MethodName ( ActualParameterList )
| Expr [ Expr ] ( ActualParameterList )
The first Expr must evaluate into an object o. The method is denoted either by the given MethodName or is the result of the Expr between the brackets. It must belong to the class of o and is called using the actual parameters specified. o becomes the current object of the called method and can so be accessed using this.

Example:

heitml input:
<def myclass4; inherit object;
   def printme><? this></def;
   return this;
 /def;
 
 x=myclass4();
 x.test="Hello";
 x.printme()>
resulting output:

myclass4(test="Hello")

Only methods defined with the
def tag can be called this way. Methods of an object defined with defenv can be called with the callenv tag however.

Environment Classes

Classes with an environment as constructor have the following additional features. Inside the content of the environment the methods of the class are visible. This means inside the content methods can be called directly using the tag syntax. The methods are not visible inside the content of any nested environments. Inside the content the object of the enclosing constructor can be accessed by parent.

Example:

heitml input:
<defenv myenv @this ... ; inherit object;
   def printme; ? this; /def;
   defbody;
 /defenv;
 
 myenv test="Hello World";
    parent.a=5;
    printme;
 /myenv>
resulting output:

myenv(test="Hello World", a=5)

Classes without Constructors

Using the
defclass tag, classes without constructors can be defined. A class defined with defclass either inherits a constructor, or it stays an abstract class.

It is useful to inherit a constructor, if the behavior of a class needs to be change by overriding some methods, without changing the constructor. This is useful for example to override the action routine of a button.

Abstract classes are useful to encapsulate some functionality that can be inherited by other classes. It is not possible to create object for an abstract class, because there is no constructor.

Nested Classes

Classes can be nested, i.e. inside a class another class can be defined. The constructor of the nested class has the same visibility as a method designed in the same class. Otherwise the class acts as if it was defined on top level. So methods of the parent class are not visible inside a nested class. The constructor method is partly a constructor of the nested class and partly a method of the enclosing class. It has the same visibility as any other method of the enclosing class and it gets the current object as a parameter. Since the constructor creates a new object however the passed current object is accessible using creator, while this denotes the newly created object.

Example:

heitml input:
<defenv myclass5; inherit object;
   def nested; inherit object;
      ? this> <\p> <
      ? creator;
   /def;
   
   this.a=5;
   nested;
 /defenv>
<myclass5></myclass5>
resulting output:

myclass5.nested()

myclass5(a=5)


This page was dynamically generated by heitml
© 1996-2008 H.E.I. All Rights Reserved