Java 继承与泛型相似
试图设计一个超类,以确保所有子类本质上是可比较的Java 继承与泛型相似,java,generics,comparable,Java,Generics,Comparable,试图设计一个超类,以确保所有子类本质上是可比较的 /** * A base class implementing Comparable with itself by delegation. * @param <T> - The type being wrapped. */ static class Distinct<T extends Comparable<T>> implements Comparable<Distinct<T>>
/**
* A base class implementing Comparable with itself by delegation.
* @param <T> - The type being wrapped.
*/
static class Distinct<T extends Comparable<T>> implements Comparable<Distinct<T>> {
final T it;
public Distinct(T it) {
this.it = it;
}
@Override
public int compareTo(Distinct<T> o) {
return it.compareTo(o.it);
}
}
/**
* A set of distinct items.
*
* @param <T>
*/
static class ThingHolder<T extends Comparable<T>> {
final Set<T> things;
public ThingHolder() {
this.things = new TreeSet<>();
}
}
/**
* A sample real thing.
*/
static class Thing extends Distinct<String> {
public Thing(String it) {
super(it);
}
}
// This doesn't work - Why?
final ThingHolder<Thing> yz = new ThingHolder<>();
/**
*一种基类,通过委托实现与自身相类似的功能。
*@param-正在包装的类型。
*/
静态类独立实现{
最后的T它;
公共信息技术(it){
this.it=it;
}
@凌驾
公共整数比较(不同的o){
返回它。比较(o.it);
}
}
/**
*一组不同的项目。
*
*@param
*/
静态类ThingHolder{
最后定案;
公共物品持有人(){
this.things=新树集();
}
}
/**
*一件实物样品。
*/
静态类事物扩展到不同的类{
公共事务(字符串){
超级(it);
}
}
//这不起作用-为什么?
最终固定器yz=新固定器();
我得到的错误是:
com/oldcurmudgeon/test/Test.java:[70,22] error: type argument Thing is not within bounds of type-variable T
where T is a type-variable:
T extends Comparable<T> declared in class ThingHolder
com/oldcurmudgeon/test/test.java:[70,22]错误:类型参数Thing不在类型变量T的范围内
其中T是一个类型变量:
T扩展类中声明的可比较ThingHolder
为什么这不起作用?可以吗?只需将
ThingHolder
类签名更改为:
static class ThingHolder<T extends Comparable> {
...
}
static class ThingHolder{
...
}
也就是说,将
从可比的中删除,这是不必要的。类事物持有者
声明事物t
必须与自身可比,但类事物扩展为独特的不是
如果将类型参数X
传递给ThingHolder
,则它必须是Comparable
的子类型(通过ThingHolder
的类声明)
因此,如果将类型Thing
传递给ThingHolder
它必须是compariable
的子类型。(在前面的语句之后,用Thing
替换X
)
Thing
扩展了Distinct
,因此实现了Comparable
(通过Thing
的类声明)
Thing
与Distinct
的类型不同-尽管它是一个子类型-因此类型匹配失败
您可以通过如下调整ThingHolder
的类声明来解决此问题:
class ThingHolder<T extends Comparable<? super T>> {
...
}
class ThingHolder提出了一些研究和抨击
通常,如果您有一个只使用类型参数T作为参数的API,那么它的使用应该利用下界通配符(?super T)
一些修补(添加?super T
)以稍微放宽限制:
/**
* A set of distinct items.
*
* Don't like the <?> in there but a <T> is not accepted.
*
* @param <T>
*/
static class ThingHolder<T extends Comparable<? super T>> {
final Set<T> things = new TreeSet<>();
}
final ThingHolder<Thing> holder = new ThingHolder<>();
/**
*一组不同的项目。
*
*不喜欢里面的,但是a是不被接受的。
*
*@param
*/
静态类ThingHolderI认为静态类不同实现可比
应该是静态类不同实现可比
@bigdestropher-但在我的情况下,应该是实现可比
,我想相互比较,不是泛型类型。关于java类型变量的漂亮谜题:)静态类ThingHolder{final Set things;..
编译,但我还没有弄清楚它是否能做到它应该做的。更新:不,它不能。我正在努力解释它,你可以尝试用String
替换t
,看看我的意思。这似乎解决了问题-但为什么?这感觉就像使用原始类型一样,可比较的是de被定义为接口可比
。我认为这里有点混乱。类型变量只是编译时的某种限制。它们什么都不存在。因此,在类ThingHolder
中,您只声明t
应该是可比的
,这没有意义-be与它本身相当,因为它是隐式的。@Andremoniy你总是可以声明class Foo实现了comparable
,这当然是愚蠢的,但也是有效的。另一方面,你可以说处理这些毫无意义的类声明不是Distinct
的责任。是的,但在这种情况下Distinct
,而不是不同的
。但是类事物扩展了不同的
应该继承可比的
不是吗?@OldCurmudgeon是的,但是自相似性要求事物
与事物
可比,而不是字符串
(通过扩展了不同的
)不过,自定界类型参数通常是有效的。我承认稍微弱化契约可以避免问题——比如@Andremoni建议使用extends Comparable
,但这仍然不能解释为什么全强度契约不起作用。对不起,我的解释毫无意义。我修复了答案。但是Distinct
imp元素具有可比性
,因此应该与ThingHolder的
匹配,但事实并非如此。我看到您采纳了我的答案……使用
约束的需要始终是设计不好的原因;对于您正在尝试的内容,必须有更好的解决方案。