Cem*_*Cem 64 java generics abstract-class
我正在尝试定义一个实现Comparable的抽象类.当我使用以下定义定义类时:
public abstract class MyClass implements Comparable <MyClass>
Run Code Online (Sandbox Code Playgroud)
子类必须实现compareTo(MyClass object).相反,我希望每个子类都能实现compareTo(SubClass object),接受自己类型的对象.当我尝试使用以下内容定义抽象类时:
public abstract class MyClass implements Comparable <? extends MyClass>
Run Code Online (Sandbox Code Playgroud)
它抱怨说"超类型可能没有指定任何通配符".
有解决方案吗?
whi*_*rra 44
在我看来,它有点过于冗长,但有效:
public abstract class MyClass<T extends MyClass<T>> implements Comparable<T> {
}
public class SubClass extends MyClass<SubClass> {
@Override
public int compareTo(SubClass o) {
// TODO Auto-generated method stub
return 0;
}
}
Run Code Online (Sandbox Code Playgroud)
seh*_*seh 19
除了你在宣布签名时遇到的机械困难之外,目标没有多大意义.您正在尝试建立一个协变比较函数,它打破了建立派生类可以定制的接口的整个想法.
如果你定义一些子SubClass类使得它的实例只能与其他SubClass实例进行比较,那么如何SubClass满足由MyClass?定义的契约呢?回想一下,MyClass它可以说它和从它派生的任何类型都可以与其他MyClass实例进行比较.你想做出不正确的SubClass,这意味着SubClass不满足MyClass的合同:你不能代替SubClass的MyClass,因为SubClass的要求是严格的.
这个问题集中在协方差和逆变,以及它们如何允许函数签名通过类型派生来改变.您可以放宽对参数类型的要求 - 接受比超类型的签名要求更宽泛的类型 - 并且您可以增强对返回类型的要求 - 承诺返回比超类型签名更窄的类型.这些自由中的每一个仍然允许完全替换派生类型的超类型; 当通过超类型的接口使用派生类型时,调用者无法区分,但是具体使用派生类型的调用者可以利用这些自由.
Willi的回答讲述了关于泛型声明的一些内容,但我建议您在以语义为代价接受该技术之前重新考虑您的目标.