是否可以在Kotlin界面中指定静态函数?

Sup*_*tar 15 static-methods interface abstract static-functions kotlin

我想做这样的事情:

interface Serializable<FromType, ToType> {
    fun serialize(): ToType
    companion object {
        abstract fun deserialize(serialized: ToType): FromType
    }
}
Run Code Online (Sandbox Code Playgroud)

甚至这对我有用:

interface Serializable<ToType> {
    fun serialize(): ToType
    constructor(serialized: ToType)
}
Run Code Online (Sandbox Code Playgroud)

但都没有编译.是否有这样的语法,或者我将被迫使用make this作为工厂的接口? 或者还有另一个答案吗?那很整洁!

hot*_*key 11

基本上,a中没有任何内容companion object可以abstractopen(并因此被覆盖),并且没有办法要求实现companion object具有方法或在接口中定义/要求构造函数.

一个可能的解决方案是将这两个函数分成两个接口:

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

interface Deserializer<FromType, ToType> {
    fun deserialize(serialized: ToType): FromType
}
Run Code Online (Sandbox Code Playgroud)

这样,您将能够在类中实现第一个接口,并使其companion object实现另一个:

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

    companion object : Deserializer<C, String> {
        override fun deserialize(serialized: String): C = C()
    }
}
Run Code Online (Sandbox Code Playgroud)

此外,还有一个严重的限制,即只有一种类型的通用特化可以用作超类型,因此这种通过接口实现进行序列化的模型可能变得不够可扩展,不允许具有不同ToTypes的多个实现.

  • 但为什么?为什么这样设计? (5认同)
  • “伴生对象”可以实现接口吗?这真是太棒了! (2认同)

小智 6

为了将来的使用,还可以将子类作为接收器参数提供给函数:

val encodableClass = EncodableClass("Some Value")
//The encode function is accessed like a member function on an instance
val stringRepresentation = encodableClass.encode()
//The decode function is accessed statically
val decodedClass = EncodableClass.decode(stringRepresentation)

interface Encodable<T> {
    fun T.encode(): String
    fun decode(stringRepresentation: String): T
}

class EncodableClass(private val someValue: String) {
    // This is the remaining awkwardness, 
    // you have to give the containing class as a Type Parameter 
    // to its own Companion Object
    companion object : Encodable<EncodableClass> {
        override fun EncodableClass.encode(): String {
            //You can access (private) fields here
            return "This is a string representation of the class with value: $someValue"
        }
        override fun decode(stringRepresentation: String): EncodableClass {
            return EncodableClass(stringRepresentation)
        }
    }
}


//You also have to import the encode function separately: 
// import codingProtocol.EncodableClass.Companion.encode
Run Code Online (Sandbox Code Playgroud)

这对我来说是更优化的用例。我们不像您的示例那样在实例化对象中使用一个函数,而在伴生对象中使用另一个函数,而是将这两个函数移动到伴生对象并扩展实例。