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

问题描述 投票:1回答:1

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

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

// 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,因为它不是我需要使用这种模式的唯一时间,它会导致大量重用代码。
oop kotlin interface jvm
1个回答
2
投票

记住类型擦除。实际上,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)

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

© www.soinside.com 2019 - 2024. All rights reserved.