web-dev-qa-db-ja.com

Kotlin:クラス内のオブジェクトとコンパニオンオブジェクトの違い

Kotlinのクラス内のオブジェクトとコンパニオンオブジェクトの違いは何ですか?

例:

class MyClass {

    object Holder {
        //something
    }

    companion object {
        //something
    }
}

含まれるパラメータ/メソッドがそのクラスに密接に関連している場合、コンパニオンオブジェクトが使用されることを既に読みました。

しかし、なぜクラスで通常のオブジェクトを宣言する可能性もあるのでしょうか?コンパニオンとまったく同じように動作しますが、名前が必要です。

「静的」(私はJava側)のライフサイクルにおそらく違いがありますか?

58
Poweranimal

オブジェクトはインターフェースを実装できます。クラス内では、ほとんどの場合、インターフェイスを実装しない単純なオブジェクトを定義してもメリットはありません。ただし、さまざまなインターフェイス(Comparatorなど)を実装する複数のオブジェクトを定義することは非常に便利です。

ライフサイクルに関しては、コンパニオンオブジェクトとクラスで宣言された名前付きオブジェクトの間に違いはありません。

33
yole

objectの使用には、expressiondeclarationの2つの異なるタイプがあります。

オブジェクト式

オブジェクト式は、クラスにわずかな変更が必要な場合に使用できますが、まったく新しいサブクラスを作成する必要はありません。匿名の内部クラスはこの良い例です。

    button.setOnClickListener(object: View.OnClickListener() {
        override fun onClick(view: View) {
            // click event
        }
    })

注意すべきことの1つは、匿名の内部クラスが外側のスコープから変数にアクセスできることです。これらの変数はfinalである必要はありません。これは、finalと見なされない匿名内部クラス内で使用される変数が、アクセスされる前に予期せず値を変更する可能性があることを意味します。

オブジェクト宣言

オブジェクト宣言は変数宣言に似ているため、割り当てステートメントの右側では使用できません。オブジェクト宣言は、シングルトンパターンの実装に非常に役立ちます。

    object MySingletonObject {
        fun getInstance(): MySingletonObject {
            // return single instance of object
        }
    }

getInstanceメソッドは、このように呼び出すことができます。

    MySingletonObject.getInstance()

コンパニオンオブジェクト

コンパニオンオブジェクトは、オブジェクトが他の言語(Javaなど)の静的オブジェクトと同様に動作できるようにする特定のタイプのオブジェクト宣言です。 companionをオブジェクト宣言に追加すると、実際の静的な概念がKotlinに存在しない場合でも、オブジェクトに「静的」機能を追加できます。インスタンスメソッドとコンパニオンメソッドを持つクラスの例を次に示します。

 class MyClass {
        companion object MyCompanionObject {
            fun actsAsStatic() {
                // do stuff
            }
        }

       fun instanceMethod() {
            // do stuff
        }
    }

インスタンスメソッドを呼び出すと、次のようになります。

    var myClass = MyClass()
    myClass.instanceMethod()

コンパニオンオブジェクトメソッドを呼び出すと、次のようになります。

    MyClass.actsAsStatic()

詳細については、 Kotlin docs を参照してください。

43
Mike

オブジェクト、またはオブジェクト宣言は、初めてアクセスされたときに遅延初期化されます。

対応するクラスがロードされると、コンパニオンオブジェクトが初期化されます。 Kotlinは本質的に静的メンバーをサポートしていませんが、「静的」エッセンスをもたらします。

4
Supriya

コンパニオンオブジェクトは、Java静的メソッド/フィールドのようにコンパニオンオブジェクトの関数/プロパティを呼び出すことができるために存在します。そして、なぜHolderが許可されているのか、ネストされたオブジェクトの宣言が違法である理由はありません。それは時々重宝するかもしれません。

3
glee8e

コンパニオンオブジェクトは、クラスがロードされるときに初期化されます(通常、実行中の他のコードによって最初に参照されるとき)。一方、Object宣言は、初めてアクセスされたときに遅延初期化されます。

https://kotlinlang.org/docs/reference/object-declarations.html を参照してください。下のセクションでは、これら2つの違いを明確に定義しています。

0
Swati Singh