Is it possible to specify a static function in a Kotlin interface?

Ben Leggiero picture Ben Leggiero · Nov 2, 2016 · Viewed 8.3k times · Source

I want to do something like this:

interface Serializable<FromType, ToType> {
    fun serialize(): ToType
    companion object {
        abstract fun deserialize(serialized: ToType): FromType
    }
}

or even this would work for me:

interface Serializable<ToType> {
    fun serialize(): ToType
    constructor(serialized: ToType)
}

but neither compiles. Is there a syntax for this, or will I be forced to use make this an interface for a factory? Or is there another answer? 😮 That'd be neat!

Answer

hotkey picture hotkey · Nov 2, 2016

Basically, nothing in a companion object can be abstract or open (and thus be overridden), and there's no way to require the implementations' companion objects to have a method or to define/require a constructor in an interface.

A possible solution for you is to separate these two functions into two interfaces:

interface Serializable<ToType> {
    fun serialize(): ToType
}

interface Deserializer<FromType, ToType> {
    fun deserialize(serialized: ToType): FromType
}

This way, you will be able to implement the first interface in a class and make its companion object implement the other one:

class C: Serializable<String> {
    override fun serialize(): String = "..."

    companion object : Deserializer<C, String> {
        override fun deserialize(serialized: String): C = C()
    }
}

Also, there's a severe limitation that only a single generic specialization of a type can be used as a supertype, so this model of serializing through the interface implementation may turn out not scalable enough, not allowing multiple implementations with different ToTypes.