Kotlin:我如何创建一个“静态”可继承函数?

时间:2016-09-03 04:17:00

标签: function kotlin

例如,我想在类型为example()的函数Child上扩展Parent,以便我可以在这两个函数上使用该函数。

Child.example()
Parent.example()

执行此操作的第一个“明显”方法是通过Parent的伴随对象,但这不允许example() Child

我尝试的第二种方法是在Parent.Companion上定义一个扩展函数,这是不方便的,因为你被迫定义一个伴随对象。对于example(),它也不允许Child

有人知道我该怎么做吗?

3 个答案:

答案 0 :(得分:21)

你要求的东西不存在,你似乎在问:

  

我可以从其后代的类引用中引用超类的伴随对象方法

或者你在问:

  

我可以从其后代的引用中引用超类的静态成员。

两者的答案是。 Kotlin的设计这是不允许的,是有意识的决定,是故意的。如果您希望更改此决定,则需要file an issue in YouTrack。 Java中的程序员通过静态方法的继承和覆盖以及从一个引用与另一个引用调用时的行为以及如何静态解析而不是动态地解决了严重混淆。 Java 8团队在向接口添加静态方法时实现了这可能造成的混乱,因此他们采用了更多的Kotlin方法,只允许接口引用调用它。为了避免这些类型的恶梦,Kotlin团队不允许这样做。正如他们不允许Java的许多其他令人困惑的方面一样。

其他答案(例如,@ voddan')通过使用companion objects为您提供解决方法,但您拒绝在评论中说明您要避免同伴对象,即使您的问题表明您正在尝试使用它们。因此,假设您不想使用它们,答案就是不能,无法完成

要摆脱伴​​侣对象,你会想谈谈Can extension functions be called in a “static” way? ......因为还不允许这会令人失望。

回到伴侣对象(对不起,但是这里是荣耀的一条路径),你也可以手动将孩子的方法委托给父母:

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()

答案 1 :(得分:14)

由于伴随对象遵循与其他对象相同的规则,因此很容易使用正常的代码重用方法:

open class Example {
    fun example() {}
}

class Parent {
    companion object : Example()
}

class Child {
    companion object : Example()
}

fun main(args: Array<String>) {
    Child.example()
    Parent.example()
}

或者使用类授权,您可以直接重用Parent中的实现:

interface Example {
    fun example()
}

class Parent {
    companion object : Example {
        override fun example() {}
    }
}

class Child {
    companion object : Example by Parent.Companion
}

答案 2 :(得分:0)

  

目的是为建筑

创建一个“替代操作员”

在Java中,当用作“构造函数”时,应使用Factory而不是静态方法。

在Kotlin方面,您可以使用顶级功能而不是工厂。

或者,如果您真的想在课堂上使用“静态方法”, 我将创建一个伴随对象并添加静态扩展方法。