[英]Confusing explanation of limiting the type parameter of a generic binary search tree in Java
我是泛型(和Java,以及Stack Overflow)的新手,我正在学习的教科书中有一点要讨论泛型二进制搜索树的实现(以下摘录)。
Comparable接口是通用的,因此让我们考虑在搜索树中存储以下类型的元素:
<T扩展了可比性<T >>
这仍然会引起问题。 假设Dog和Cat都是Mammal类的子类,并且Mammal类实现Comparable接口。 现在,如果我们创建一个存储哺乳动物对象的二进制搜索树,则可以添加“狗”和“猫”,但它们之间并没有真正的可比性。 因此,如果以这种特定方式使用此解决方案,则与使用Comparable的非通用版本存在相同的问题。 一个更全面的解决方案,尽管在理论上并不令人满意,但将通用类型编写为:
<T扩展了Comparable <? 超级T >>
该声明将元素的可比性限制为T的任何超类。
因此,我明白了为什么类型参数需要为Comparable< T>
,但随后该书声称,如果Mammal
的树包含尝试相互调用compareTo()
方法的不同子类型,则可能会带来问题。 好吧,如果树中Cat
和Dog
对象的引用类型是Mammal
,那么它们还是不会调用Mammal
的compareTo()
方法(是Comparable< Mammal>
),从而使其成为有效的比较(仅在Mammal
水平)?
我不知道Comparable< ? super T>
什么区别Comparable< ? super T>
Comparable< ? super T>
做,因为那不是同一回事,除非如果Mammal
不是Comparable
那么它会退回Comparable
超类,例如Animal
类或其他东西吗?
我可能会丢失某些东西,例如某些讨厌的类型擦除结果,或者某些会导致比较无法正常工作的东西,就像我认为的那样。
好的,因此您了解<T extends Comparable<T>>
可与以下类一起使用:
class Mammal extends Comparable<Mammal>
现在您有了Mammal
的子类Cat
: class Cat extends Mammal
。 由于继承, Cat
还实现了Comparable<Mammal>
,并且正如您所说,由于它是从Mammal
继承的compareTo(Mammal)
方法,因此它可以与所有哺乳动物(当然包括猫)进行比较。
但是现在的问题是Cat
不能与绑定的<T extends Comparable<T>>
,因为Cat
没有实现Comparable<Cat>
。 您不能通过让Cat
实现Comparable<Cat>
来解决此问题,因为您只能实现带有一个类型参数的接口。
但是从概念上讲,对Cat
列表进行排序没有问题,因为Cat
可以与其他Cat
进行比较(它们可以与所有哺乳动物进行比较,这比较笼统;但要点是它们可以与Cat
进行比较)。 因此,问题在于我们的界限过于严格。
<T extends Comparable<? super T>>
<T extends Comparable<? super T>>
解决了此问题,并允许使用Cat
。 回想一下PECS规则-生产者extends
super
消费者。 好吧,Comparable是消费者而不是生产者,因为您将T类型的参数传递到其compareTo
方法(consume)中,但是没有方法需要返回T类型(produce)。 因此, super
通配符是合适的。
抱歉,改写这个让我更清楚
考虑接口
< T extends Comparable<T> >
然后考虑您的子类别Cat
Cat extends Comparable<Cat>
如果还有其他类(如Dog),这会破坏二进制搜索树中的许多内容,因为Comparable需要两个相同类型的类。 猫应该看起来像这样
Cat extends Comparable<Animal>
作者将其更改为
< T extends Comparable<? super T> >
这样我们现在可以添加对象
Cat extends Comparable<Animal>
因为进入Comparable的参数必须是超类而不是类本身。 因此它可以是哺乳动物->动物->对象,但不能是字符串
要点是这个。 您选择的类应该实现参数为Self的Comparable接口,也可以是将Base类作为可比较参数的任何其他超类。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.