子接口的类型参数存在“不一致的值”

FHT*_*ell 4 oop jvm interface kotlin

所以我有可以用不同方式比较的对象。我有一个类层次结构,其中基础对象必须定义如何以各种可能的方式进行比较,而对于一些要比较的子类,有一种标准方法,因此可以为这些方法提供默认值。

这很难用语言解释,所以这里有一些代码

// This is akin to how `Comparable<in T>` is defined
interface AllComparisons<in T> {
    // this interface has all the possible comparison methods
    fun cmp1(other: T): Int
    fun cmp2(other: T): Int
}

interface SomeComparisons<in T>: AllComparisons<T> {
    // this interface has a default for some comparison methods
    override fun cmp2(other: T) = -this.cmp1(other)  // eg
}


// This is akin to how a comparable object `Obj: Comparable<Obj>` is defined
abstract class BaseClass: AllComparisons<BaseClass>  // must define both cmp1 and cmp2

abstract class SubClass: BaseClass(), SomeComparisons<SubClass>  // only must define cmp1
Run Code Online (Sandbox Code Playgroud)

这会在最后一行引发编译器错误:

Type parameter T of 'AllComparisons' has inconsistent values: BaseClass, SubClass
Run Code Online (Sandbox Code Playgroud)

我的问题是:

  1. 为什么这是不允许的?这是编译器限制还是实际上存在逻辑不一致?

  2. 我能做些什么来修复它?我不想将默认逻辑 (for cmp2) 从SomeComparisonsinto移动,SubClass因为这不是我唯一需要使用此模式的时间,并且会导致大量重复使用的代码。

Ale*_*nov 6

记住类型擦除。在这些方法AllComparisonsSomeComparisons实际上

fun cmp1(other: Object): Int
fun cmp2(other: Object): Int
Run Code Online (Sandbox Code Playgroud)

当你实施

override fun cmp2(other: BaseClass)
Run Code Online (Sandbox Code Playgroud)

在 中BaseClass,您还将获得编译器生成的

override fun cmp2(other: Object) = cmp2(other as BaseClass)
Run Code Online (Sandbox Code Playgroud)

SubClass继承了该实现,但要实现SomeComparisons<SubClass>需要

override fun cmp2(other: Object) = cmp2(other as SubClass)
Run Code Online (Sandbox Code Playgroud)

当然,您不能同时拥有两者。