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的
    匹配,但事实并非如此。我看到您采纳了我的答案……使用
    约束的需要始终是设计不好的原因;对于您正在尝试的内容,必须有更好的解决方案。