方法的动态调度

结构化类型的行为由它的方法表示。 只能对结构化类型的实例调用这些方法。 创建子类型时,除继承属性以外,它还将继承为超类型定义的方法。 因此,对于超类型,还可以针对其子类型的任何实例运行该超类型的方法。

如果您不希望将为超类型定义的方法用于特定子类型,那么可以覆盖此方法。 覆盖方法意味着专门为给定的子类型重新实现该方法。 这使您能够方便地动态调度方法(也称为多态性),即,应用程序将根据结构化类型实例的类型(例如,该方法在结构化类型层次结构中所处的位置)来执行最具体的方法。

要定义覆盖方法,请使用 CREATE TYPE(或者 ALTER TYPE)语句,并在 METHOD 子句之前指定 OVERRIDING 子句。 如果未指定 OVERRIDING,那么将使用原始方法(属于超类型)。 对于要定义的覆盖方法,必须满足下列条件:
  • 您要创建(或者改变)的类型必须是您打算覆盖其方法的结构化类型的子类型。
  • 您要声明的方法的特征符(该方法的名称和参数列表),与属于该超类型的方法的特征符完全相同。
  • 覆盖方法必须准确地隐式覆盖一个原始方法。
  • 您打算覆盖的例程是用户定义的结构类型实例方法。
  • 原始方法不是使用 PARAMETER STYLE JAVA 声明的。

以下示例说明了用于覆盖方法的一个样本方案:

数据类型:
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);
在这种情况下,a 是超类型。 类型 bca 的子类型。 最终,db 的子类型
方法:
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 | ".";

这里的原始方法是 fooA。 fooB, fooC, fooD 明确覆盖fooA。 fooD 隐式覆盖 fooB fooA。 同样,fooB 将隐式覆盖 fooA,fooC 将隐式覆盖 fooA。 (注意,显式覆盖隐含隐式覆盖。)