如何通过绑定接口实例化此类参数化?

时间:2016-03-09 12:16:22

标签: java generics interface

我有3个接口:

dcast(melt(setDT(df1), id.var='Name')[order(-value), 
      .SD, Name][, N:=1:.N , .(Name)],
        Name~N, value.var=c("variable", "value"))

然后有两个类实现了这两个第一个接口:

public interface IAggregable<TElement extends IAggregable<TElement, TResult>, TResult> {
    TResult aggregate(TResult intermediateResult);
}

public interface IDeeplyCloneable<TElement extends IDeeplyCloneable<TElement>> {
    TElement deepClone();
}
public interface IContainer<TElement extends IAggregable<TElement, TResult> & IDeeplyCloneable<TElement>, TResult> {
    TResult aggregateAllElements();
    TElement cloneElementAtIndex(int index);
}

几乎完全一样

public class Person implements IAggregable<Person, Integer>, IDeeplyCloneable<Person> {
    private int age;

    public Integer aggregate(Integer intermediateResult) {
        if (intermediateResult == null) {
            return age;
        }
        return age + intermediateResult;
    }

    public Person deepClone() {
        Person clone = new Person();
        clone.age = age;
        return clone;
    }

    @Override
    public String toString() {
        return "Person [age=" + age + "]";
    }

}

然后终于 public class Car implements IAggregable<Car, Integer>, IDeeplyCloneable<Car> { private int horsepower; public Integer aggregate(Integer intermediateResult) { if (intermediateResult == null) { return horsepower; } return horsepower + intermediateResult; } public Car deepClone() { Car clone = new Car(); clone.horsepower = horsepower; return clone; } @Override public String toString() { return "Car [horsepower=" + horsepower + "]"; } } 假设实现UselessContainer并且能够同时拥有IContainerPerson以及任何其他类的任何其他对象实现CarIAggregable

IDeeplyCloneable

问题:如何创建班级public class UselessContainer<TElement extends IAggregable<TElement, TResult> & IDeeplyCloneable<TElement>, TResult> implements IContainer<TElement, TResult> { private ArrayList<TElement> list; public UselessContainer() { this.list = new ArrayList<>(); } public void add(TElement element) { list.add(element); } @Override public TResult aggregateAllElements() { return null; } @Override public TElement cloneElementAtIndex(int index) { return null; } @Override public String toString() { return list.toString(); } } 的对象?

我已经尝试过:UselessContainer

2 个答案:

答案 0 :(得分:0)

您已将UselessContainer标记为已绑定到IAggregable和IDeeplyCloneable。请查看&符号,该符号表示业务实体必须实现这两个接口才能添加到列表中。

为了在代码中使用它 - 只需创建UselessContainer的实例而不指定具体的泛型类型:

   UselessContainer uc = new UselessContainer();
    uc.add(new Person()); // works!
    uc.add(new Integer(1)); // won't compile
    uc.add(new Car()); // works!

我刚刚在我的编辑器中尝试过它(JDK8)。

编辑: 您可以创建包装类:

class SimpleContainer {
    public <TElement extends IAggregable<TElement, TResult> & IDeeplyCloneable<TElement>, TResult> void add(TElement el) {
        UselessContainer<TElement, TResult> uc = new UselessContainer<>();
        uc.add(el);
    }
}

并使用它:

   SimpleContainer sc = new SimpleContainer();
        sc.add(new Person());

答案 1 :(得分:0)

UselessContainer<A, B>您想要满足2个条件(将其缩短为U<A,B>):

(1)Car可以添加到U<A, B>

(2)Person可以添加到U<A, B>

实现(1)和(2)都是不可能的,可以使用间接证明来证明:

假设可以满足这两个条件。

add的签名是add(TElement element)方法和TElement extends IAggregable<TElement, TResult>

从(1)和Car implements IAggregable<Car, Integer>我们可以推断出A=Car

从(2)和Person implements IAggregable<Person, Integer>我们可以推断出A=Person

结合这两个结果我们得到Car=Person这显然是错误的。这个矛盾总结了证据。

这意味着您必须修改类型参数的限制或使用原始类型。