Java 抽象类 实现具有泛型的接口

2022-08-31 13:51:15

我正在尝试定义一个实现可比的抽象类。当我使用以下定义定义类时:

public abstract class MyClass implements Comparable <MyClass>

子类必须实现 。相反,我希望每个子类都实现,接受自己类型的对象。当我尝试用类似的东西定义抽象类时:compareTo(MyClass object)compareTo(SubClass object)

public abstract class MyClass implements Comparable <? extends MyClass>

它抱怨“超类型可能不会指定任何通配符。

有解决方案吗?


答案 1

在我看来,这有点太冗长了,但有效:

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

}

答案 2

除了在声明签名时遇到的机械困难之外,这个目标没有多大意义。您正在尝试建立一个协变比较函数,这打破了建立派生类可以定制的接口的整个想法。

如果您定义了某个子类,使其实例只能与其他实例进行比较,那么如何满足由 定义的协定?回想一下,这是说它和从它派生的任何类型都可以与其他实例进行比较。你试图让 这不是真的,这意味着它不满足 的合同:你不能代替 ,因为 的要求更严格。SubClassSubClassSubClassMyClassMyClassMyClassSubClassSubClassMyClassSubClassMyClassSubClass

这个问题集中在协方差和逆变上,以及它们如何允许函数签名通过类型派生进行更改。您可以放宽对参数类型的要求(接受比超类型的签名要求更宽的类型),并且可以加强对返回类型的要求,从而承诺返回比超类型的签名更窄的类型。这些自由中的每一个仍然允许将派生类型完美地替换为超类型;通过超类型的接口使用派生类型时,调用方无法分辨出区别,但使用派生类型的调用方可以具体利用这些自由。

Willi的回答教会了一些关于泛型声明的知识,但我敦促你在以牺牲语义为代价接受这项技术之前重新考虑你的目标。


推荐