Java:超类的通用接口
想象一下下面的代码:Java:超类的通用接口,java,generics,interface,Java,Generics,Interface,想象一下下面的代码: class A {} class B extends A {} interface IA extends Iterable<A> {} interface IB extends Iterable<B> {} 甚至 interface IB extends Iterable<B> implements IA {} 接口IB扩展了Iterable实现IA{} 但是,编译器确实不喜欢这两种类型,如果允许这样做,那么我的代码会更好,因为概
class A {}
class B extends A {}
interface IA extends Iterable<A> {}
interface IB extends Iterable<B> {}
甚至
interface IB extends Iterable<B> implements IA {}
接口IB扩展了Iterable实现IA{}
但是,编译器确实不喜欢这两种类型,如果允许这样做,那么我的代码会更好,因为概念上B可以用作A,而无需到处上转换
我有什么解决方案可以解决这个问题呢?Java中的泛型不是协变的——也就是说,
List instanceof List
为false。因此,IB
不是IA
的一个实例,因此我相信这是导致编译器问题的原因
想象一个新类,类C扩展了{}
。C是A,因此C将是IA要包含的合法值,但不是IB。因此,如果您尝试将IB用作IA实例,则可能插入C并破坏类型安全保证。这意味着您想要的内容不可行(至少在一般情况下不可行)
然而,也许能解决你的具体问题?e、 g
void methodThatOperatesOnA(Iterable<? extends A> it) {
...
}
void方法OperateSona(IterableA类型不能有两个超级类型G和G,其中X!=Y
——可能是由于擦除
解决问题的一种方法是对要迭代的类型使用类型参数
interface IA<X extends A> extends Iterable<X>
{
@Override Iterator<X> iterator();
}
interface IB extends IA<B>
{
@Override Iterator<B> iterator();
}
这样会更好吗
public interface Iterable<T>
Iterator<? extends T> iterator();
公共接口不可编辑
迭代器很难看出这有什么用处;假设您想要的东西是可能的,您可以添加一个您想如何使用IB
的示例吗?大图:A
是用户,B
是管理员。IA
列出来自不同来源的用户,IB列出来自其他来源的管理员。当我使用IB
我也希望能够将它传递给那些期望IA
s的函数,因为它们是兼容的。是的。我该如何解决它或提供更好的API?我假设这就是原因,问题是如何修复它。我认为没有一个解决方案没有令人讨厌的检查和强制转换实例。+1这是他们bes的通配符t、 吹毛求疵:这些“少数古怪案例”是什么?IIRCnull
尽可能地涵盖了制作人所能消费的内容。@PaulBellora:这与“通配符捕获”有关。所以你可以做类似于list.add(list.get(0))的事情
。上一次我检查你不能这样做,但是-在某处有一篇关于它的帖子。@PaulBellora:啊,也许你不能。TBH,我只读过关于它的文章,我从来没有在实践中需要这样做。@PaulBellora它不必使用原始类型。`void swap(List List List){swap2(List);}void swap2(List){List.set(I,List.get(j))}请参阅JLS 5.1.10中的示例,但我认为您的解决方案不会编译,因为您正在更改返回类型。编辑:nm,它之所以有效是因为协变返回类型,明白了。我选择此解决方案是因为它易于集成、工作和清除。
class Team implements Iterable<Member>
{
public Iterator<Member> iterator() { ... }
}
for(Member member : team) ...
class Team
{
Iterable<Member> members() { ... }
}
for(Member member : team.members()) ...
interface IA
{
Iterable<? extends A> members();
}
interface IB extends IA
{
@Override
Iterable<? extends B> members();
}
public interface Iterable<T>
Iterator<T> iterator();
public interface Iterable<T>
Iterator<? extends T> iterator();