ypeparameters:
泛型参数
一般意义上来说,泛型是一种把相同的代码重用在不同的类型上的技术。它作为一个相对独立于其它面向对象特性的技术,在面向对象语言里已经变得越来越普遍了。我们这里之所以讨论泛型,一是因为泛型这种技术本身就很让人感兴趣,另外,也是因为泛型是一个被用来对付二元方法问题(binarymethodproblem)的主要工具。
和subtyping共同使用,泛型可以用来解决一些在方法特化等场合由反协变带来的类型系统的困难。考虑这样一个例子:
我们有Person和Vegitarian两种类型,同时,我们有Vegitable和Food两种类型。而且,Vegitable<:food.>
ObjectTypePersonis
…
methodeat(food:Food);
end;
ObjectTypeVegetarianis
…
methodeat(food:Vegitable);
end;
这里,从常识,我们知道一个Vegitarian是一个人。所以,我们希望可以有Vegetarian<:person.>
不幸的是,因为参数是反协变的,如果我们错误地认为Vegetarian<:person>
使用泛型技术,我们引入TypeOperator(也就是,从一个类型导出另一个类型,概念上类似于对类型的函数)。
ObjectOperatorPersonEating[F<:food>
…
methodeat(food:F);
end;
ObjectOperatorVegetarianEating[F<:vegetable>
…
methodeat(food:F);
end;
这里使用的技术被称作BoundedTypeParameterization.(Trelli/Owl,Sather,Eiffel,PolyTOIL,Raptide以及GenericJava都支持BoundedTypeParameterization.其它的语言,如C++,只支持简单的没有类型约束的泛型)
F是一个类型参数,它可以被实例化成一个具体的类型。类似于变量的类型定义,一个bound如F<:vegitable>
于是,我们有:
对任意F<:vegitable>
对于原来的Vegitarian类型,我们有:
Vegetarian=VegetarianEating[Vegetable]<:personeating>
这种关系,正确地表达了“一个素食者是一个吃蔬菜的人”的概念。
除了BoundedTypeParameterization之外,还有一种类似的方法也可以解决这个素食者的问题。这种方法被叫做:BoundedAbstractType
请看这个定义:
ObjectTypePersonis
TypeF<:food>
…
varlunch:F;
methodeat(food:F);
end;
ObjectTypeVegetarianis
TypeF<:vegitable>
…
varlunch:F;
methodeat(food:F);
end;
这里,F<:food>
在创建Person对象时,我们可以先选定一个Food的subtype,比如说,F=Dessert.然后,用一个Dessert类型的变量赋给属性lunch.最后再实现一个eat(food:Dessert)的方法。
这样,Vegetarian<:person>
这种方法的局限在于,Person,Vegitarian只能吃他们自带的午餐。你不能让他们吃买来的午餐。导入 在此 参考资料end 参考资料