web-dev-qa-db-ja.com

Kotlinインターフェースで静的関数を指定することは可能ですか?

私はこのようなことをしたいです:

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

それとも私にとってはうまくいくでしょう:

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

しかし、どちらもコンパイルされません。 これには構文がありますか、それともファクトリーのインターフェースにする必要がありますか? または別の答えはありますか? ????それはきちんとしているでしょう!

16
Supuhstar

基本的に、companion objectの何もabstractまたはopenにすることはできません(したがってオーバーライドできます)。また、実装のcompanion objectsにメソッドを要求する方法はありません。または、インターフェースでコンストラクタを定義/要求します。

考えられる解決策は、これらの2つの機能を2つのインターフェースに分離することです。

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。

13
hotkey

私はKotlinで比較的新しいです。これが私の2¢です

  1. コンパニオンオブジェクトはクラスのインスタンスであるため、継承できません。これが、抽象関数を実装する場所がない理由です。 Javaでは、同様の結果には、抽象クラスを実装する匿名クラスが必要ですが、クラスのインスタンスのオーバーライドメソッドとは大きく異なります。

  2. インターフェイスを使用してインスタンスを作成することはできないため、インターフェイスでコンストラクタを使用することはできません。

なぜジェネリック抽象クラスを作成しないのですか?次に、抽象関数またはオープン関数は、serialize():ToTypeとdeserialize(serialized:ToType):FromType関数の両方で機能します。

1
C.A.B.