Kotlin: How can I create a “static” inheritable function?

What you are asking for does not exist, you appear to be asking:

Can I reference a companion object method of a superclass from a class reference of its descendants

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.

The other answers (@voddan’s for example) are giving you work-arounds to have the same feel of calling syntax by using companion objects but you reject those in your comments by saying you want to avoid a companion object, even though your question states you are trying to use them. So assuming you do not want to use them, the answer is simply 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.

Going back to companion objects (sorry, but they are the one path to glory here), you can also just manually delegate the method of the child to the parent:

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

Or as extensions:

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

Leave a Comment