Java:关于数据结构和通配符的泛型

时间:2015-11-16 19:03:11

标签: java generics inheritance wildcard

我试图学习如何使用泛型,为此,我创建了自己的数据结构,类似于带有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>"

我真的不明白为什么会这样。我很确定我以某种方式弄乱了类型参数,而且我真的不确定在哪里。这应该可以以某种方式解决(至少不删除任何类/接口 - 类头可能并且可能完全搞砸了)。提前感谢您提供的任何帮助。

1 个答案:

答案 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的原始格式;你应该在那里提供一个类型参数。