树的一种用法是用编程语言表示表达式。如前一节所述,表达式类型由一个抽象类表示,每种表达式都由一个子类表示。有一种抽象方法来评估一个表达式,并且每个子类都根据相应的表达式实现该方法。
使用泛型时,可以通过表达式的类型对表达式类型进行参数化。例如,Exp<Integer>
是一个返回整数的表达式,而 Exp<Pair<Integer,Integer>>
是一个返回一对整数的表达式。
例 9-4
演示了具有泛型的解释器模式。它首先定义一个类 Pair<A,B>
,并带有一个构造函数和两个方法来选择一对的左右分量。然后它为一个抽象类 Exp<A>
声明一个返回 A
类型值的表达式,抽象方法 eval
返回 A
类型的值。在我们的例子中,有五种表达式:
Exp<Integer>
类型的整数文字Exp<Integer>
类型的和表达式,它有两个子表达式,每个类型都是Exp<Integer>
- 一个表达式,用于构造
Exp<Pair<A,B>>
类型的对,该对具有Exp<A>
和Exp<B>
类型的两个子表达式。 - 一个表达式,用于选择
Exp<A>
类型的一个对的左侧组件,它具有Exp<Pair<A,B>>
类型的子表达式。 - 一个表达式,用于选择
Exp<B>
类型的对的右部分,它具有类型Exp<Pair<A,B>>
的子表达式。
有五种静态方法对应于五种表达式,每种都返回表达式类的适当子类的实例,并具有适当的 eval
方法定义。最后,主要方法构造并评估示例表达式。
Java
中的泛型受到功能语言(如 ML
和 Haskell
)中类似功能的启发。通用的解释器模式很有趣,因为它展示了一种Java中的泛型比其他语言中的泛型更强大的方式。虽然最近的 Haskell
版本包含了一个实验性特征,即通用抽象数据类型,它专门为支持这种模式而设计,但在 ML
和 Haskell
的标准版本中实现这种模式是不可能的。