Как мне объявить переменную, используя ее интерфейс как универсальный - PullRequest
1 голос
/ 02 апреля 2020

Я конвертирую некоторый код Java в Kotlin, и я столкнулся с кодом, который по сути работает следующим образом:

interface Animal {}

class Dog : Animal {}

interface Leash<in T: Animal> {
    fun attachToCollarOf(animal: T)
}

class DogLeash : Leash<Dog> {
    override fun attachToCollarOf(animal: Dog) {
        TODO("Not yet implemented")
    }
}

val foo: Leash<Animal> = DogLeash

При попытке назначить foo с помощью учитывая тип DogLeash(), я получаю следующую ошибку: error: type mismatch: inferred type is DogLeash but Leash<Animal> was expected. Есть ли комбинация in, out или with, которая позволит мне выполнить задание в последней строке?

1 Ответ

3 голосов
/ 02 апреля 2020

Нет. in делает типы контравариантными , поэтому DogLeash не является подтипом Leash<Animal>. Ссылка типа Leash<Animal> позволит вам вызывать attachToCollarOf для любого Animal, тогда как DogLeash может работать только с Dog s - компилятор по праву запрещает это назначение. Вместо этого, если у вас было:

class AnimalLeash : Leash<Animal> {
    override fun attachToCollarOf(animal: Animal) {
        println("Attached to Animal")
    }
}

Тогда выполнение val leash: Leash<Dog> = AnimalLeash() сработало бы: ссылка на Leash<Dog> позволяет вам вызывать attachToCollarOf только на Dog с, но любой AnimalLeash работает для Dog.

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