我正在尝试混合接口(interface),为现有接口(interface)添加附加功能。例如。我有一个接口(interface)过滤
interface Filtering<T, E>{
T filter(Filter<E> f);
}
我可以轻松地将其添加到现有接口(interface)中:
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)
有什么方法可以将此功能定义为混合接口(interface),以便我可以转换 Container<E>
至Container<X>
还有SomeOtherContainer<E>
至SomeOtherContainer<X>
?
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? */ >{
}
就我个人而言,我认为这是不可能的,我认为我需要将转换方法添加到每个目标接口(interface)中,但我还没有完全失去希望。有人可以帮忙吗?
澄清:Transformer
函数将个体 E
转换为元素到X
元素。我不要Transformer
从 Container<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);
}
});
顺便说一句:我知道我可以在 Guava 中做类似的事情。对于这个问题,让我们忽略这个事实,这与功能(我可以轻松实现)无关,而是与泛型的使用有关。
最佳答案
不幸的是,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,别逼我写出来,推断出来!
尽管如此,这样的推论可能会给漫不经心的观察者带来错误的安全感。 有手动类型转换,是精神上的,但不是书面的。我个人非常关心这个推理规则。这违背了静态类型的要点,也就是说,我们想要显式地写下所有类型。
关于java - 混合接口(interface)的通用参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5025669/