Kotlin中如何通过父类引用访问子类隐藏成员?
Kotlin父类引用访问子类隐藏成员的问题
先看你给出的示例代码:
abstract class Animal(val size: Int) class Dog(val cuteness: Int): Animal(345) var dog: Dog = Dog(10) var animal: Animal = dog var x = 0 // 此处设断点
你观察到的现象是对的:在代码层面,animal变量被声明为Animal类型,所以只能访问Animal类定义的size成员,看不到Dog的cuteness;但Android Studio调试器能直接显示cuteness的值,这是因为调试器直接读取JVM内存中的对象实例数据,不受编译期静态类型约束。
关于你提问的「能否通过代码访问这些隐藏成员」,你的核心理解是对的——常规编码场景下受Kotlin静态类型检查限制,不能直接访问,但有两种合法方式可以实现:
1. 类型转换(推荐)
如果能确定animal的实际类型是Dog,可以通过类型转换来解锁子类成员:
- 安全转换(推荐,避免类型转换异常):
if (animal is Dog) { // 智能转换后,animal自动被识别为Dog类型 println(animal.cuteness) }
- 强制转换(仅当你100%确定类型匹配时使用):
val dogInstance = animal as Dog println(dogInstance.cuteness)
2. 反射(不推荐常规场景使用)
通过Kotlin反射API可以绕过编译期类型检查,直接读取对象的成员属性:
import kotlin.reflect.full.memberProperties // 获取cuteness属性 val cutenessProp = animal::class.memberProperties.firstOrNull { it.name == "cuteness" } // 读取属性值 val cutenessValue = cutenessProp?.call(animal) println(cutenessValue) // 输出10
反射会跳过编译期检查,性能开销大且可读性差,除非是框架开发等特殊场景,否则不建议使用。
总结:你最初的判断没问题——日常写代码时Kotlin的语法规则确实限制了直接访问,但并非完全无法实现,类型转换是常规场景下的解决方案。
内容的提问来源于stack exchange,提问作者Johann
相关产品推荐
相关产品推荐

