21

我想做这样的事情:

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

甚至这对我有用:

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

但都不编译。有没有这样的语法,还是我会被迫使用使它成为工厂的接口? 或者还有别的答案吗?那会很整洁!

4

2 回答 2

20

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

您可能的解决方案是将这两个功能分成两个接口:

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

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

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

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

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

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

于 2016-11-02T06:27:59.297 回答
1

我对 Kotlin 比较陌生。这是我的 2¢

  1. 伴生对象是类的实例,因此不能继承。这就是为什么抽象函数没有地方实现的原因。在 Java 中,类似的结果需要匿名类实现抽象类,但与覆盖类实例的方法有很大不同。

  2. 接口不能用于创建实例,所以接口中没有构造函数。

为什么不创建通用抽象类?然后 abstract 或 open 函数将适用于 serialize(): ToType 和 deserialize(serialized: ToType): FromType 函数。

于 2017-08-28T20:57:09.393 回答