我有以下接口:
public interface Assembler<T, S> {
S assemble( T val);
}
public interface Slicer<T, V> {
V[] slice(T val);
}
我想让Assembler实例使用Slicer实例并调用它的slice()。我有以下内容:
public class MyAssembler<T, S> implements Assembler<T, S> {
private final Slicer<T, V> slicer;
//ctor
public MyAssembler() {
slicer = new MySlicer<T, V>();
}
@Override
public S assemble(T val) {
V[] v = mySlicer.slice(val);
}
这不能编译,因为MyAssembler中的V类型未知(无法解析为某种类型)。我无法将Assembler接口更改为Assembler<T, S, V>
。还有另一种方法可以定义依赖关系吗?这不是非泛型类的问题。即使使用静态工厂方法来获取对Slicer的引用,仍然存在未知V的问题。有什么建议?如果无法做到这一点,任何人都可以推荐一种不同的方法或设计模式,允许汇编程序调用切片器的切片()吗?
答案 0 :(得分:0)
继承将解决您的问题,而不是撰写,如下所示:
public class MyAssembler<T,S,V> extends MySlicer<T,V> implements Assembler<T,S> {
public MyAssembler() {
}
@Override
public S assemble(T val) {
V[] v = this.slice(val);
...
}
}
答案 1 :(得分:0)
汇编程序总是将Slicer作为其两个泛型之一吗?如果是这样,您只需要定义一个泛型,并将Slicer作为非泛型成员变量。
但是,如果泛型类型可能是也可能不是Slicer,您可以实现特殊处理,当其中一个 具有反射的切片器时,尤其是if (v instanceof Slicer)
,然后转换为切片器如果是真的。
答案 2 :(得分:0)
由于您的S
和V
是通用的,因此您可以将它们换成任何其他类型,甚至是其他类型。你可以这样做:
public class MyAssembler<T, S> implements Assembler<T, S> {
private final Slicer<T, S> slicer;
public MyAssembler() {
slicer = new MySlicer<T, S>();
}
@Override
public S assemble(T val) {
S[] v = slicer.slice(val);
return v[0]; // for example
}
}
我所做的是将T
和S
定义为相同的类型。在我自己的实现中,我可以毫无问题地做到这一点。
答案 3 :(得分:0)
将Sotirios Delimanolis的评论作为答案。
要允许在MyAssembler中使用V,请声明MyAssembler<T, S, V> extends Assembler<T, S>
。要使用它,请为ex:Assembler<Integer, Integer> asmblr = new MyAssembler<Integer, Integer, Integer>
实例化。