在 Java 语言的 Jam 扩展中,mixin 的超类类型没有名称;我们就不能在 mixin 主体中引用它。这一限制会迅速引起一连串各种其它问题。例如,在 Jam 中,禁止程序员将 this 作为参数传递给方法;无法对这样的调用进行类型检查。这一限制的影响极大,因为许多最常见的设计模式都要依靠于能够将 this 作为参数传递。
请考虑访问者模式,其中用 for 方法为复合层次结构中的每个类都定义了访问者类。通常被访问的类包含 accept 方法,它采用访问者并传递 this 来调用该访问者的方法。因此,在 Jam 中,访问者模式不能和 mixin 一起使用。
将 mixin 明确表述为泛型类,我们就始终有父类的句柄,它是该类继续的类型参数。例如,我们可以将 Scrollable 的父类引用为类型 T。其结果是,在答应将 this 作为类型参数传递时没有任何根本性的困难。
解决这一问题的各种方案与我们上月第 3 部分中讨论的针对检查 new 表达式的类型参数所提出的解决方案完全一致,因为超级构造函数调用和 new 表达式都引用了给定类的同一个类构造函数。让我们回顾一下这些解决方案:
需要一个不带参数的(zeroary)构造函数,用于所有类型参数的实例化。 当没有匹配的构造函数时,抛出运行时异常。 包含额外的类型参数注释,告知我们这些实例化必须包含哪些构造函数。 就如 new 表达式的情况,前两个解决方案有严重缺陷。通常在类定义中包含不带参数的构造函数没有任何意义。而且,当不存在任何匹配的构造函数时就抛出异常也不太理想。究竟静态类型检查主要是严格防止那种异常。
第三种解决方案可能有点繁琐,但是它有许多优点。注释类型参数,其中包括所有实例化都必须拥有的构造函数集。这些注释确切地告知我们针对类型参数,我们可以可靠地调用什么样的构造函数。因此,当类型参数 T 用作泛型类的超类时,T 的注释确切地告知我们可以调用哪些超级构造函数。假如 T 不包含注释,那么类型检查器会禁止它用作超类。