You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 08:30:58