混合接口的通用参数

时间:2011-02-17 06:16:12

标签: java generics

我正在尝试使用mixin接口为现有接口添加额外功能。例如。我有一个界面过滤

interface Filtering<T, E>{

    T filter(Filter<E> f);

}

我可以轻松地将其添加到现有界面:

interface Container<E> extends Filter<Container<E>, E>{
    // translated type: Container<E> filter(Filter<E> f);
}

现在,我还希望有一种转换行为,使用语法

Container<E>转换为Container<X>
Container<X> transform(Transformer<E,X> transformer)

有什么方法可以将此功能定义为混合界面,以便我可以将Container<E>转换为Container<X>,还可以将SomeOtherContainer<E>转换为SomeOtherContainer<X>?< / p>

interface Transforming< /* what goes in here? >{

    < /* and what goes in here? */ > X transform(Transformer<S,T> transformer);
}

interface Container<E> extends Transforming<Container<E>, /* and in here? */ >{
}

就个人而言,我认为不可能,我认为我需要将转换方法添加到每个目标接口,但我还没有完全失去希望。有人可以帮忙吗?

澄清Transformer功能会将各个E元素转换为X个元素。我不希望TransformerContainer<E>转换为Container<X>,这将完全没用。

这就是我想用它的方式:

Container<Integer> intVersion = // initialize it
Container<String> hexVersion =
    intVersion.transform(new Transformer<Integer,String>(){
       public String apply(Integer input){
           return Integer.toHexString(input);
       }
});

BTW:我知道我可以在番石榴做类似的事情。让我们忽略这个问题的事实,这不是关于功能(我可以轻松实现),而是关于泛型使用。

2 个答案:

答案 0 :(得分:1)

不幸的是,Java不允许这样做:

interface Transforming<E, X>
    <T> X<T> transform(Transformer<E,T> transformer);

interface Container<E> extends Transforming<E, Container>

即使它确实如此,也不够通俗;我们想要一个函数映射T到另一个包含T

的类型
interface Transforming<E, f>
    <T> f(T) transform(Transformer<E,T> transformer);

interface Container<E> extends Transforming<E, {T->Container<T>} >

但足够的幻想。你能做的最好的事情就是在回报类型上非常模糊:

interface Transforming<E>
    <X,T> X transform(Transformer<E,T> transformer);

interface Container<E> extends Transforming<E>

注意,我们无法在X和T之间表达任何约束。

现在您的示例代码编译,没有任何警告!!根据作业有一种类型推断,X被认为是Container<String>

一方面,这种推断的类型安全性完全取决于程序员提供正确的目标类型。如果他把Container<Rope>放在左边,它也会在没有警告的情况下编译。

另一方面,如果Java没有进行这样的推断,那么我们必须返回Object而不是X,并对返回对象进行手动转换;手动模型的安全性当然也完全取决于程序员提供正确的目标类型。因此有人争辩说,为什么我们要惩罚自己呢?如果我将A分配给B,当然A是B,请不要强迫我写出来,推断它!

尽管如此,这种推断可能会给不经意的观察者带来虚假的安全感。 是精神上的手动演员,但不是写作。我个人非常关心这个推理规则。这与静态类型的关键在于,即我们想要明确地写下所有类型。

答案 1 :(得分:0)

你可以尝试(我对语法没有完全的信心,但我认为它很接近):

interface Transforming<X> {
    <Y> Y transform(Transformer<X, Y> transformer);
}

interface Container<E> extends Transforming<Container<E>> {
}

然后您的Container将具有转换功能。类型Y将根据变换器的实际调用确定,基于Transformer对象传递给变换的Y.

这不会保证Y必然是Container类型,但也许Transformer中的某些东西可以给出限制。