2014-03-24 35 views
1

跟进this question,但我会尽量让它自成一体。如何使扩展接口与通用参数兼容?

假设我有一个名为Animal的接口,这对于各种原因具有代表实现类泛型类型参数:

public interface Animal<A extends Animal<A>> 

我也有一个子接口,Dinosaur,其行为以同样的方式:

public interface Dinosaur<D extends Dinosaur<D>> extends Animal<D> 

现在我有一个类Lizard它实现Animal

public class Lizard implements Animal<Lizard> 

和一个子类,Trex,它实现Dinosaur

public class Trex extends Lizard implements Dinosaur<Trex> 

这四个声明现在产生错误。这是因为类Trex实现了两次接口Animal,但具有不同的类型参数:由于它扩展了Lizard,它实现了接口Animal<Lizard>,并且由于它实现了Dinosaur<Trex>,它实现了Animal<Trex>

Animal<Trex>不是Animal<Lizard>子接口,即使TrexLizard一个子类,所以我们得到一个编译错误。

我敢肯定,有一些解决方法使用通配符,但我无法弄清楚它是什么。

这里的东西,你可以编译得到了同样的错误:

public class InterfaceTest 
{ 
    private interface Animal<A extends Animal<A>> {} 

    private interface Dinosaur<D extends Dinosaur<D>> extends Animal<D> {} 

    private class Lizard implements Animal<Lizard> {} 

    private class Trex extends Lizard implements Dinosaur<Trex> {} 
} 

回答

2

This is because the class Trex implements the interface Animal twice, but with different type parameters

是啊,这样的话,这里面的这个直接周围也没有路 - 这是一个技术上的限制,因为仿制药使用擦除实现。 永远不能在具有不同通用参数的多个类上实现相同的接口。当通用类型被删除时,最终会以相同的方式扩展两个接口,无法区分使用这些不同通用类型的方法,因此运行时无法确定要执行哪种方法。

对于您的特定用例,可能有一种解决方法,这意味着您不必使用不同的类型参数实现相同的接口,但没有更多细节,不可能说出可能的内容。

编辑:看看链接的问题,它看起来像你可以解决这个问题,通过使用其他答案(你还没有接受),以这种方式指定返回值,而不是在类上声明:

public <T extends JNumber> T add(T addend); 

这应该那么意味着你不需要声明你的类和接口的泛型类型参数,然后因此不应该有这个问题。

+1

是的 - 使用其他答案正是我想到的解决方法。非常感谢您的帮助。 –

+0

@ Donkey_2009没问题。 – berry120