Tuesday, June 23, 2009

Inheritance and Constructors

Constructors are subject to the following inheritance rules.

Instance Constructors

Each class has an instance constructor called constructor. This name does not comply with the rule of unique component names within a path of an inheritance tree. Consequently, the instance constructors of the individual classes of an inheritance tree are totally independent of each other.

  • Instance constructors of superclasses cannot be redefined in subclasses.
  • They cannot be called explicitly using [CALL METHOD] constructor.

This avoids namespace conflicts.

The instance constructor of a class is called when you create an object using the CREATE OBJECT statement. Since a subclass inherits all attributes from its superclasses that are visible to it, and since the content of these attributes can be set by instance constructors of its classes, the instance constructor of a subclass is responsible for ensuring that the instance constructors of all superclasses are called as well. This requires that the instance constructor of each subclass contains a [CALL METHOD] super->constructor call of the instance constructor of the direct superclass even if it is not explicitly declared. Exceptions to this rule are the direct subclasses of the root node object.

In superclasses that do not have an explicitly defined instance constructor, the implicit instance constructor is called. This constructor automatically ensures that the instance constructor of the next higher superclass is called.

When instance constructors are called, all non-optional input parameters of these constructors must be populated, as follows:

  • Parameter population at CREATE OBJECT

    Starting from the class of the created objects, the first explicitly defined instance constructor in the corresponding path of the inheritance tree is taken into account. This is the instance constructor of the class itself or the first explicitly defined instance constructor of a superclass.
  • Population at [CALL METHOD] super->constructor

    Starting from the direct superclass, the first explicitly defined instance constructor in the corresponding path of the inheritance tree is taken into account.

The interface of the first explicitly defined instance constructor is populated as is the case with a normal method - that is,

  • If no input parameters exist, no parameters are passed.
  • Optional input parameters can be populated using EXPORTING.
  • Non-optional input parameters must be populated using EXPORTING.

If there are no explicitly defined instance constructors in the path of the inheritance tree below the root class object, no parameters are passed.

Both at CREATE OBJECT and at [CALL METHOD] super->constructor, the next possible explicit instance constructor must be taken into account. If one exists, its interface must be populated. The same applies to exception handling in instance constructors. Using inheritance requires in-depth knowledge of the entire inheritance tree since when an object of a class is created that resides on a deep level of the tree, parameters may have to be passed to the constructor of a class that resides closer to the root node.

The instance constructor of a subclass is split into two parts by the [CALL METHOD] super->constructor call, which is required from a syntactical point of view. In the statements before the call, the constructor behaves like a static method. This means it cannot access the instance attributes of its class. It is only after the call that instance attributes can be addressed. The statements before the call are used to determine actual parameters for the interface of the instance constructor of a superclass. Only static attributes or local data can be used for this.

When a subclass is instantiated, the system makes a nested call of the instance constructors from the subclass to the superclasses where the instance attributes can only be addressed at the deepest nesting level, that is, in the highest superclass. When the system returns to the constructors of the underlying subclasses, their instance attributes can then also be successively addressed.

The methods of subclasses are not visible in constructors. If an instance constructor calls an instance method of the same class using the implicit self reference me, the method is called as it is implemented in the class of the instance constructor and not as the possibly redefined method of the subclass to be instantiated. This is an exception to the rule that when instance methods are called the implementation is always called in the class to whose instance the reference currently points.

Static Constructors

Each class has a static constructor called class_constructor. As far as the namespace in an inheritance tree is concerned, the static constructor is subject to the same rules as the instance constructor.

The static constructor is called when a subclass is first addressed within a program. However, all preceding static constructors of the entire inheritance tree must have been executed before. Otherwise, a static constructor can only be called once at the runtime of the program. This is why when a subclass is addressed for the first time the system searches the next higher superclass whose static constructor has not yet been called. This static constructor is executed first. Afterwards the constructors of all subsequent subclasses are called successively down to the subclass addressed.

No comments:

Blog Archive