Тип Параметр подчиненного интерфейса имеет «противоречивые значения» - PullRequest
1 голос
/ 01 апреля 2019

Итак, у меня есть объекты, которые можно сравнивать по-разному. У меня есть иерархия классов, в которой базовые объекты должны определять, каким образом можно сравнивать все возможные способы, тогда как для сравнения некоторых подклассов существует стандартный способ, поэтому эти методы могут иметь значения по умолчанию.

Это сложно объяснить словами, вот код

// 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 Ответ

1 голос
/ 01 апреля 2019

Помните о стирании типов.Методы в AllComparisons и SomeComparisons на самом деле

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)

И, конечно, вы не можете иметь и то и другое одновременно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...