例如,我想在扩展ParentChild类型上有一个函数example(),这样我就可以在两个类型上都使用这个函数.

Child.example()
Parent.example()

要做到这一点,第一种"明显"的方法是通过Parent的伴生对象,但这不允许Childexample().

我try 的第二种方法是在Parent.Companion上定义一个扩展函数,这很不方便,因为您必须定义一个伴随对象.它也不允许example()代表Child.

有人知道我怎么做吗?

推荐答案

你所要求的并不存在,你似乎在问:

我可以从超类的子类引用中引用它的伴生对象方法吗

or maybe you are asking:

Can I reference a static member of a superclass from a reference of its descendants.

The answer for both is no. It is by design of Kotlin that this is disallowed, was a conscious decision, was intentional. If you wish to change this decision you would need to file an issue in YouTrack. Programmers in Java were heavily confused by the inheritance and overriding of static methods and the behavior when called from one reference versus another and how it is statically resolved rather than dynamically. Java 8 team when adding static methods to interfaces realize the confusion this could cause so they took a more Kotlin approach of only allowing it to be called by the interface reference. To avoid these types of nightmares, the Kotlin team disallowed it. Just as they disallowed many other confusing aspects of Java.

其他答案(例如@voddan的答案)给你提供了一些变通方法,让你在使用companion objects时有同样的调用语法的感觉,但你在 comments 中拒绝了这些方法,说你想避开一个伴随对象,即使你的问题表明你正试图使用它们.所以假设你不想使用它们,答案就是no, can't be done.

To get rid of the companion object, you would want to talk about Can extension functions be called in a “static” way? ... which will be disappointing since it is not yet allowed.

回到companion objects(抱歉,这里它们是通往荣耀的唯一途径),您也可以手动将子对象的方法委托给父对象:

open class Parent {
    companion object { // required, sorry, no way around it!
        fun foo() = /* some cool logic here */
    }
}

class Child: Parent() {
    companion object {  // required, sorry, no way around it!
        fun foo() = Parent.foo() 
    }
}

或作为扩展:

open class Parent {
    companion object {} // required, sorry, no way around it!
}

class Child: Parent() {
    companion object {} // required, sorry, no way around it!
}

fun Parent.Companion.foo() = /* some cool logic here */
fun Child.Companion.foo() = Parent.foo()

Kotlin相关问答推荐

如何为集成测试配置Gradle JVM测试套件?

KTOR';S函数`staticResources`在Kotlin本机目标上不可用

如何通过更改现有数据类型来执行Android房间数据库迁移?

在Kotlin lambda的参数中如何指定函数类型?

如何从 Period.between() 返回的字符串中提取信息? (Kotlin )

可组合项在返回后返回时组合导航句柄

Kotlin 函数中接收者和参数的类型相同

根据字符串值动态过滤数组列表 - kotlin

OnClickListener 未在 ConstraintLayout 上触发

如何使用 gradle 脚本 Kotlin 构建文件构建可运行的 ShadowJar?

致命错误 LifecycleOwners 必须在 registerForActivityResult 开始之前调用 register

如何在顶级函数中使用 koin 注入依赖项

Kotlin:找不到符号类片段或其他 android 类

如何将vararg转换为list?

Firestore - 如何在 Kotlin 中排除数据类对象的字段

使用 Kotlin 创建自定义 Dagger 2 范围

Kotlin中OnclickListener方法之间的差异

在 Kotlin 函数上使用 Mokito anyObject() 时,指定为非 null 的参数为 null

这是 Kotlin 中的错误还是我遗漏了什么?

在 Kotlin 中声明 Byte 会出现编译时错误The integer literal does not conform to the expected type Byte