我试图学习如何使用泛型,为此,我创建了自己的数据结构,类似于带有Iterator的列表。
最上面的类声明为:
public class BasicList<A> implements Iterable {
}
它只是一个包含节点的列表和一个指向下一个元素的指针。
另一个名为DescendingList的列表几乎完全相同,只是这次,由于迭代器不同,你得到了另一个输出。我给这个List一个比较器让迭代器工作。比较器只是一个接口:
public interface Bigger<A> {
boolean bigger(A x);
}
DescendingList如下所示:
public class DescendingList<A extends Bigger<A>> extends BasicList<A> implements Iterable {
}
这个想法是它可以与任何类型的对象一起使用,可以通过Bigger界面进行比较。
现在我有一个抽象类:
public abstract class Rock implements Bigger<Rock> {
}
最后,一个扩展Rock类的普通类:
public class Mineral extends Rock {
}
所以,手头的问题是,虽然我可以轻松地创建一个填充Minerals的新BasicList,如下所示:
BasicList<Mineral> min = new BasicList<Mineral>();
我不能对DescendingList做同样的事情。每当我尝试使用
时DescendingList<Mineral> min = new DescendingList<Mineral>();
我的IDE(IntelliJ)全部
"Type parameter "Rock" is not within it's bound; should implement Bigger<Mineral>"
我真的不明白为什么会这样。我很确定我以某种方式弄乱了类型参数,而且我真的不确定在哪里。这应该可以以某种方式解决(至少不删除任何类/接口 - 类头可能并且可能完全搞砸了)。提前感谢您提供的任何帮助。
答案 0 :(得分:2)
Mineral
不是Bigger<Mineral>
,而是Bigger<Rock>
,而且与Bigger<Mineral>
不兼容,因为即使是Mineral
}是Rock
,Java的泛型是不变的。它必须是Bigger<Rock>
因为Rock
的定义方式 - 实施Bigger<Rock>
- 并且DescendingList
将类型参数A
声明为{{ 1}}。
因为它是一个使用者(类型参数作为方法参数),所以类型参数Bigger<A>
在其声明中需要一个下界(超级)。
A
这种方式class DescendingList<A extends Bigger<? super A>> // ...
将在其自己的范围内。
顺便说一句,您正在Mineral
中实施Iterable
的原始格式;你应该在那里提供一个类型参数。