Запечатанный класс в Kotlin, ошибка несовместимых типов

У меня есть следующий код Kotlin. Запечатанный класс под названием Animalи два класса объектов Dog а также Cat наследуется от запечатанного класса Animal, Я получаю эту ошибку в when пункт в случае Кэт.

Incompatible types: Cat and Dog

Почему это дает эту ошибку? Как я могу использовать запечатанный класс в Kotlin для этого типа операций? Является ли закрытый класс хорошим выбором для проведения полиморфизма?

sealed class Animal {
  abstract fun speak()
}

object Dog : Animal() {
    override fun speak() { println("woof") }
}

object Cat : Animal() {
    override fun speak() { println("meow") }
}

fun main(args: Array<String>) {
    var i = Dog
    i.speak()
    when(i) {
        is Dog -> {
            print("Dog: ")
            i.speak()
        }
        is Cat -> {
            print("Cat: ")
            i.speak()
        }
    }
}

2 ответа

Решение

Недостающая часть var i: Animal = Dog

В основном компилятор жалуется на типы - Cat не является подтипом Dog (но они оба являются подтипами Animal, поэтому, если вы явно установите код базового типа, он будет компилироваться и работать

У вашего кода есть две точки, которые компилятор, в целом, не очень понимает:

  1. Внутри вашего when предложение, вы проверяете, является ли ваша переменная типа Dog действительно is Dog,
  2. Внутри вашего when пункт, вы также проверьте, является ли ваша переменная типа Dog это Cat,

Это немного противоречит компилятору, так как оба типа совместно используют только супер тип. Проблема действительно в том, что ваша переменная явно не объявляет свой тип. В результате присвоения Dog экземпляр вашего var i компилятор выводит его тип, который, конечно, Dog, Все впоследствии имеет смысл: нет необходимости проверять тип экземпляра, это определенно Dog,

Чтобы код работал, нужно объявить var i: Animal, явно напечатано. Кроме того, всегда подумайте об использовании val в пользу var,

Другие вопросы по тегам