继承通用接口的子类

时间:2013-08-23 12:30:58

标签: java generics

我有一个界面可以确保对象可以复制自己:

public interface Duplicable<T extends Duplicable<T>> {
    public T duplicate();
}

我现在有

class X implements Duplicable<X>

但我也有一个延伸X的Y类。

这不是问题,直到我需要另一个通用类:

public class DoStuffWithDuplicable<T extends Duplicable<T>>

我不能使用Y的通用版本的DoStuffWithDuplicable,因为它不实现Duplicable<Y>而是Duplicable<X>,因为它从X继承它。

所以我试过

public class DoStuffWithDuplicable<T extends Duplicable<? super T>>

..但这意味着后来引入了一个不安全的演员

(T) obj.duplicate()

在代码体中。类参数也更复杂,类的使用更难以理解。任何想法如何解决这个问题?

2 个答案:

答案 0 :(得分:1)

我可能没有正确理解你的问题,但我会试一试。

首先,为什么你有一个像这样扩展自己的界面?

您可以尝试的是:

public interface Duplicable<T> {
    public T duplicate();
}

然后当你使用另一个你希望泛型参数为Duplicable的类时,你可以这样做:

public class X<T extends Duplicable<T>> {
    code...
}

现在,当您从X继承时,子类中的任何通用组件都必须是可复制的。

答案 1 :(得分:1)

在Java中无法做到这一点。

假设您对类型为Y的对象调用obj.duplicate()。然后,类型系统只能确保它将返回类型为X的对象,因为Y实现了Duplicate&lt; X&gt ;.

但你可以创建一个DoStuffWithDuplicable&lt; X&gt;并将Y对象传递给它。

    DoStuffWithDuplicable<X> blub = new DoStuffWithDuplicable<X>();
    Y y = (Y) blub.doStuff(new Y());

对于返回值,库的客户端可以使用安全转换,因为他可能知道具体的类型。

另一种选择是在库中使用不安全的强制转换并手动检查类型:

class DoStuffWithDuplicable<T extends Duplicable<? super T>> {
    T doStuff(T obj) {
        @SuppressWarnings("unchecked")
        T t = (T) obj.duplicate();
        if (!t.getClass().equals(obj.getClass())) 
            throw new ClassCastException("...");
        return t;
    }
}