Dynamic dispatch of methods

The behavior for a structured type is represented by its methods. These methods can only be invoked against instances of their structured type. When a subtype is created, among the attributes it inherits are the methods defined for the supertype. Hence, a supertype's methods can also be run against any instances of its subtypes.

If you do not want a method defined for a supertype to be used for a particular subtype, you can override the method. To override a method means to reimplement it specifically for a given subtype. This facilitates the dynamic dispatch of methods (also known as polymorphism), where an application will execute the most specific method depending on the type of the structured type instance (for example, where it is situated in the structured type hierarchy).

To define an overriding method, use the CREATE TYPE (or ALTER TYPE) statement, and specify the OVERRIDING clause before the METHOD clause. If OVERRIDING is not specified, the original method (belonging to the supertype) will be used. For an overriding method to be defined, the following conditions must be met:
  • The type you are creating (or altering) must be a subtype of the structured type whose method you intend to override.
  • The signature (the method's name and parameter list) of the method you are declaring is identical to that of a method belonging to the supertype.
  • An overriding method must implicitly override exactly one original method.
  • The routine you intend to override is a user-defined structured type instance method.
  • The original method is not declared with PARAMETER STYLE JAVA.

The following example demonstrates a sample scenario for the overriding of methods:

Data types:
CREATE TYPE a AS (z VARCHAR(20))
    METHOD foo(i INTEGER) RETURNS VARCHAR(80)
        LANGUAGE SQL;

CREATE TYPE b UNDER a AS (y VARCHAR(20))
    OVERRIDING METHOD foo(i INTEGER) RETURNS VARCHAR(80);

CREATE TYPE c UNDER a AS (x VARCHAR(20))
    OVERRIDING METHOD foo(i INTEGER) RETURNS VARCHAR(80);

CREATE TYPE d UNDER b AS (w VARCHAR(20))
    OVERRIDING METHOD foo(i INTEGER) RETURNS VARCHAR(80);
In this situation, a is the supertype. Types b and c are subtypes of a. Finally, d is the subtype of b
Methods:
CREATE METHOD foo(i INTEGER) FOR a
  RETURN "In method foo_a. Input: " | char(i) | self..z | ".";

CREATE METHOD foo(i INTEGER) FOR b
  RETURN "In method foo_b. Input: " | char(i) | self..z |
         " y = " | self..y | ".";

CREATE METHOD foo(i INTEGER) FOR c
  RETURN "In method foo_c. Input: " | char(i) | self..z |
         " y = " | self..y | " x = " | self..x | ".";

CREATE METHOD foo(i INTEGER) FOR d
  RETURN "In method foo_d. Input: " | char(i) | self..z |
         " y = " | self..y | " w = " | self..w | ".";

The original method here is fooA. fooB, fooC, and fooD explicitly override fooA. fooD implicitly overrides fooB and fooA. Similarly, fooB implicitly overrides fooA, and fooC implicitly overrides fooA. (Note that explicit overriding implies implicit overriding.)