我正在尝试学习如何使用泛型,为此,我正在创建自己的数据结构,类似于带有Iterator和all的列表。

最上层的类声明为:

public class BasicList<A> implements Iterable {
}


它只是一个带有节点的列表和指向下一个元素的单个指针。

还有一个名为DescendingList的列表,它的功能几乎相同,只是这次,由于Iterator不同,您获得了另一个输出。我给此列表提供一个比较器,以使迭代器正常工作。比较器只是一个接口:

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 {
}


因此,当前的问题是,尽管我可以轻松地创建一个新的BasicList,其中填充了如下的Minerals:

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>"


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

最佳答案

Mineral不是Bigger<Mineral>,它是Bigger<Rock>,并且与Bigger<Mineral>不兼容,因为即使MineralRock,Java的泛型也是不变的。由于Bigger<Rock>的定义方式(实现Rock)并且Bigger<Rock>声明类型参数DescendingListA,因此必须为Bigger<A>

因为它是使用者(类型参数作为方法参数),所以类型参数A的声明需要下限(超级)。

class DescendingList<A extends Bigger<? super A>> // ...


这样,Mineral将位于其自己的范围内。

顺便说一句,您正在Iterable中实现BasicList的原始格式。您应该在那里提供类型实参。

07-25 21:53