Kotlin中的密封类,不兼容类型错误

时间:2018-01-06 00:09:19

标签: kotlin sealed-class

我有以下Kotlin代码。一个名为Animal的密封类和两个对象类DogCat继承自密封类Animal。我在Cat案例中的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 个答案:

答案 0 :(得分:4)

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

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

答案 1 :(得分:1)

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

  1. when子句中,检查Dog类型的变量是否真的is Dog
  2. 在您的when子句中,检查您的Dog类型的变量是否为Cat
  3. 这与编译器有点矛盾,因为两种类型只相互共享一个超类型。问题实际上是你的变量没有显式声明它的类型。由于将Dog实例分配给var i,编译器会推断其类型,当然这是Dog。之后的一切都有意义:无需检查实例类型,它绝对是Dog

    要使代码生效,您必须声明var i: Animal,明确键入。另外,always consider using val in favor of var