子接口的类型参数具有“不一致的值”

时间:2019-04-01 13:36:56

标签: oop kotlin interface jvm

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

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

// 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

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

Type parameter T of 'AllComparisons' has inconsistent values: BaseClass, SubClass

我的问题是:

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

  2. 该如何解决?我宁愿不要将cmp2的默认逻辑从SomeComparisons移到SubClass,因为这不是我唯一一次使用此模式,并且会导致很多重用的代码。

1 个答案:

答案 0 :(得分:1)

记住类型擦除。 AllComparisonsSomeComparisons中的方法实际上是

fun cmp1(other: Object): Int
fun cmp2(other: Object): Int

以及实施

override fun cmp2(other: BaseClass)

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

override fun cmp2(other: Object) = cmp2(other as BaseClass)

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

override fun cmp2(other: Object) = cmp2(other as SubClass)

当然不能同时拥有两者。