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

Kotlin中的密封类,不兼容类型错误,kotlin,sealed-class,Kotlin,Sealed Class,我有下面的Kotlin代码。一个名为Animal的密封类和两个对象类Dog和Cat继承自密封类Animal。我在is Cat案例中的when子句中遇到此错误 Incompatible types: Cat and Dog 为什么会出现这个错误?如何使用Kotlin中的密封类来执行此类型的操作?sealed类是执行多态性的好选择吗 sealed class Animal { abstract fun speak() } object Dog : Animal() { overrid

我有下面的Kotlin代码。一个名为
Animal
的密封类和两个对象类
Dog
Cat
继承自密封类
Animal
。我在is Cat案例中的
when
子句中遇到此错误

Incompatible types: Cat and Dog
为什么会出现这个错误?如何使用Kotlin中的密封类来执行此类型的操作?sealed类是执行多态性的好选择吗

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()
        }
    }
}
密封类动物{
抽象趣味演讲()
}
对象狗:动物(){
重写fun speak(){println(“woof”)}
}
对象猫:动物(){
重写fun speak(){println(“meow”)}
}
趣味主线(args:Array){
变量i=狗
i、 讲
何时(i){
是狗->{
打印(“狗:”)
i、 讲
}
是猫->{
打印(“Cat:”)
i、 讲
}
}
}

缺少的部分是
变量i:Animal=Dog


基本上,编译器在抱怨类型-
Cat
不是
狗的子类型(但它们都是
动物的子类型),这就是为什么如果显式设置基类型代码将编译并工作

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

  • when
    子句中,检查类型为
    Dog
    的变量是否真的
    是Dog
  • when
    子句中,还检查
    Dog
    类型的变量是否为
    Cat
  • 这与编译器有点矛盾,因为这两种类型彼此只共享一个超级类型。真正的问题是您的变量没有显式声明其类型。将
    Dog
    实例分配给
    var i
    ,编译器会推断其类型,当然是
    Dog
    rds很有意义:不需要检查实例类型,它肯定是一只


    要使代码正常工作,您必须声明显式类型的
    var i:Animal
    。此外,.

    在这种情况下使用密封类与抽象类有什么好处吗?密封类是否适合这样做多态性?@s-hunter,当您有一组封闭的类型并且想要打开功能时,密封类是合适的您添加的可选性通常会针对集合中的每个类型以不同的方式实现,而不要求这些类型符合某些公共接口。@s-hunter好吧,密封类与polymorhism并不真正相关,它们只是提供语义来描述有限层次结构并使用它,例如,在
    when
    construction@ruX,它还是l多态性。如果你有一个动物和一个适用于任何动物的函数,你调用该函数,其行为取决于你所拥有的动物的实际类型。你可以在不更改函数调用的情况下更改实际类型,并获得不同的行为。这种多态性与基于遗传的多态性之间的主要区别在于编写新的函数不需要修改任何内容,但添加新类型就可以了。