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

Kotlin中如何获取方法参数的精确类型并访问对应属性?

解决方案

方案1:抽象公共属性(优先推荐)

这是最符合面向对象设计的方案,从根源上避免重复的类型判断:
如果可以修改父类BasicListItem,直接将两个子类共有的title、description属性提升到父类中声明:

open class BasicListItem(
    open val title: String,
    open val description: String
)

// 子类继承父类,重写对应属性即可
data class Post(
    override val title: String,
    override val description: String,
    // Post 独有属性
    val author: String
) : BasicListItem(title, description)

data class Review(
    override val title: String,
    override val description: String,
    // Review 独有属性
    val rating: Int
) : BasicListItem(title, description)

改造后不需要任何类型判断,直接在方法中访问父类属性即可:

fun setupListItemViews(item: BasicListItem) {
    item_title.text = item.title
    item_descr.text = item.description
    // 若需要处理子类独有属性,配合Kotlin智能转换即可
    when(item) {
        is Post -> item_sub.text = "作者:${item.author}"
        is Review -> item_sub.text = "评分:${item.rating}星"
    }
}

如果无法修改父类BasicListItem的定义,可以抽离公共接口让两个子类实现:

interface IListItemDisplay {
    val title: String
    val description: String
}

data class Post(/*原有属性*/) : BasicListItem(), IListItemDisplay
data class Review(/*原有属性*/) : BasicListItem(), IListItemDisplay

方法参数可直接使用IListItemDisplay类型,同样可以直接访问公共属性。

方案2:封装类型判断工具(适合无法修改类结构的场景)

如果不能修改父类和子类的定义,可以封装通用的类型处理工具,避免多个方法重复写类型判断逻辑:
首先写一个高阶扩展函数统一处理类型分发:

inline fun <R> BasicListItem.runByType(
    onPost: (Post) -> R,
    onReview: (Review) -> R
): R = when(this) {
    is Post -> onPost(this)
    is Review -> onReview(this)
    else -> throw IllegalArgumentException("不支持的列表项类型:${javaClass.simpleName}")
}

所有需要区分类型的方法直接调用该工具即可,不需要重复写类型判断:

fun setupListItemViews(item: BasicListItem) {
    item.runByType(
        onPost = { post ->
            item_title.text = post.title
            item_descr.text = post.description
            // 处理Post专属逻辑
        },
        onReview = { review ->
            item_title.text = review.title
            item_descr.text = review.description
            // 处理Review专属逻辑
        }
    )
}

如果仅需要访问公共属性,也可以直接封装扩展属性,进一步简化调用:

val BasicListItem.title: String
    get() = when(this) {
        is Post -> this.title
        is Review -> this.title
        else -> ""
    }

val BasicListItem.description: String
    get() = when(this) {
        is Post -> this.description
        is Review -> this.description
        else -> ""
    }

封装后直接调用item.title、item.description即可,不需要任何额外判断。

内容的提问来源于stack exchange,提问作者G. Rann

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 00:39:03