Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin: How can I create a "static" inheritable function?

For example, I want to have a function example() on a type Child that extends Parent so that I can use the function on both.

Child.example() Parent.example() 

The first "obvious" way to do this is through the companion object of Parent, but this doesn't allow example() for Child.

The second way I tried was defining an extension function on Parent.Companion, which is inconvenient because you are forced to define a companion object. It also doesn't allow example() for Child.

Does anybody know how I can do this?

like image 667
Jire Avatar asked Sep 03 '16 04:09

Jire


People also ask

Can we create static methods in Kotlin?

Kotlin is a statically typed programming language for the JVM, Android and the browser, 100% interoperable with Java. Blog of JetBrains team discussing static constants in Kotlin.

How do I make Kotlin static?

In order to implement a static method in Kotlin, we will take the help of "companion objects". Companion objects are the singleton objects whose properties and functions are tied to a class but not to the instance of that class. Hence, we can access them just like a static method of the class.

How do I use Kotlin inheritance?

Everything in Kotlin is by default final, hence, we need to use the keyword open in front of the class declaration to make it inheritable for other classes. Kotlin uses operator ":" to inherit a class.

Do we have anything called static in Kotlin?

One way in which the Kotlin language differs from Java is that Kotlin doesn't contain the static keyword that we're familiar with. In this quick tutorial, we'll see a few ways to achieve Java's static method behavior in Kotlin.


1 Answers

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() 
like image 190
7 revs, 2 users 98% Avatar answered Sep 18 '22 12:09

7 revs, 2 users 98%