4

我有以下 Kotlin 代码。一个称为密​​封类Animal,以及两个对象类DogCat继承自密封类Animal。我when在 is Cat 案例的子句中收到此错误。

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()
        }
    }
}
4

2 回答 2

6

缺少的部分是var i: Animal = Dog

基本上编译器在抱怨类型 -Cat不是的子类型Dog(但它们都是 的子类型Animal,这就是为什么如果你明确设置基本类型代码将编译并工作

于 2018-01-06T00:13:26.027 回答
1

您的代码有两个地方,编译器作为一个整体并不真正理解:

  1. 在您的when子句中,您检查您的变量类型是否Dog真的is Dog
  2. 在您的when子句中,您检查您的变量类型Dog是否为 a Cat

这与编译器有点矛盾,因为这两种类型只共享一个超类型。问题实际上是您的变量没有明确声明其类型。由于将Dog实例分配给您的var i,编译器推断其类型,当然是Dog. 之后的一切都是有意义的:无需检查实例类型,它绝对是一个Dog.

为了使代码工作,你必须声明var i: Animal,显式类型。此外,请始终考虑val使用var.

于 2018-01-06T04:08:05.080 回答