如何在Kotlin中将超类对象转换为子类对象?

时间:2020-10-08 14:03:04

标签: java android oop kotlin

在这里,我试图将超类对象转换为子类。我收到运行时错误,因为“无法转换类”。

例如:

class Animal {}
class Cat : Animal() {}

class abc {
fun abcd(): Animal {
    return Animal()
}

fun getData() {
    val cat: Cat = abcd() as Cat     //Giving me runtime error.
}
}

2 个答案:

答案 0 :(得分:3)

您不能将基类“实例”强制转换为子代类,因为基类不一定实现其子代的行为,而子代对此一无所知。

在您的特定示例中,方法 abcd()返回基类 Animal 的实例,因此无法将其强制转换为 Cat ,因为动物可能没有中定义的任何行为。

例如,假设您还有一个 Dog 类,并且 Cat Dog 都实现了不同的方法,例如 dog。 fetch() cat.jump()。这种行为在动物基类中不存在,因此无法明确地将其转换为特定动物。

相反的说法是正确的,因此将 Cat 强制转换为 Animal ,因为 Cat 继承了其基类 Animal

相反,您可以做的是在 abcd()中实例化 Cat ,并仍然返回 Animal

fun abcd(): Animal {
    return Cat()
}

这是有效的,并且强制转换将起作用。但是,如果混合派生类,例如在返回类型为 Animal <的情况下实例化 Dog 时,则必须注意避免在运行时出现 ClassCastException 。 / strong>,并尝试将其用作 Cat

小注释::我假设您的示例中动物打开的原因仅仅是复制/粘贴错误,因为显然需要这样的关键字才能允许继承。

答案 1 :(得分:1)

也许您正在尝试做的事情是创建一个类型,然后根据子类型进行操作,例如:

sealed class Animal

data class Cat(val...) : Animal()
data class Dog(val...) : Animal()

class YourMapper {
    fun animal(condition: Type): Animal {
        return when(condition) {
            ... -> Dog(...)
            ... -> Cat(...)
        }
    }

    fun getData(condition: Type): Animal {
        return animal(condition)
    }

然后用法是

val data = YourMapper().getData(condition)
when(data) {
  is Dog -> {/*do something with your dog*/}
  is Cat -> {/*do something with your cat*/} 
}