在这里,我试图将超类对象转换为子类。我收到运行时错误,因为“无法转换类”。
例如:
class Animal {}
class Cat : Animal() {}
class abc {
fun abcd(): Animal {
return Animal()
}
fun getData() {
val cat: Cat = abcd() as Cat //Giving me runtime error.
}
}
答案 0 :(得分:3)
您不能将基类“实例”强制转换为子代类,因为基类不一定实现其子代的行为,而子代对此一无所知。
在您的特定示例中,方法 abcd()返回基类 Animal 的实例,因此无法将其强制转换为 Cat ,因为动物可能没有猫中定义的任何行为。
例如,假设您还有一个 Dog 类,并且 Cat 和 Dog 都实现了不同的方法,例如 dog。 fetch()和 cat.jump()。这种行为在动物基类中不存在,因此无法明确地将其转换为特定动物。
相反的说法是正确的,因此将 Cat 强制转换为 Animal ,因为 Cat 继承了其基类 Animal 的行为。 strong>。
相反,您可以做的是在 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*/}
}