泛型类之间的依赖关系

时间:2014-03-04 19:38:02

标签: java generics

我有以下接口:

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的问题。有什么建议?如果无法做到这一点,任何人都可以推荐一种不同的方法或设计模式,允许汇编程序调用切片器的切片()吗?

4 个答案:

答案 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)

由于您的SV是通用的,因此您可以将它们换成任何其他类型,甚至是其他类型。你可以这样做:

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
    }
}

我所做的是将TS定义为相同的类型。在我自己的实现中,我可以毫无问题地做到这一点。

答案 3 :(得分:0)

将Sotirios Delimanolis的评论作为答案。

要允许在MyAssembler中使用V,请声明MyAssembler<T, S, V> extends Assembler<T, S>。要使用它,请为ex:Assembler<Integer, Integer> asmblr = new MyAssembler<Integer, Integer, Integer>实例化。