定数の宣言とコンパニオンオブジェクトの使用は、Kotlinの重要な概念であり、Javaの静的メンバーに代わって登場し、オブジェクト指向プログラミング(OOP)と関数型プログラミングのパラダイムの交差点での課題に対応しています。
歴史的背景: Javaでは、定数には通常static finalフィールドを使用し、静的メソッドはユーティリティまたはファクトリ関数のために使用されます。 Kotlinでは、staticの代わりにobjectとcompanion objectが導入され、compile-time定数にはconstキーワードが使用されます。
問題: インスタンスに依存しない値を宣言し、ファクトリメソッドや静的状態を管理しながらOOPの整合性を保つ必要があります。
解決策: コンパニオンオブジェクト(companion object)はクラス内で宣言され、すべてのインスタンスに共通するメンバーを配置することを可能にします:
コード例:
class MyClass { companion object { const val DEFAULT_LIMIT = 10 fun create(): MyClass = MyClass() } } val limit = MyClass.DEFAULT_LIMIT val instance = MyClass.create()
主な特徴:
コンパニオンオブジェクトはクラス内で複数のインスタンスを持つことができますか?
いいえ、1つのクラスには1つのコンパニオンオブジェクトのみが存在できます。 2つ目を宣言しようとするとコンパイルエラーになります。しかし、コンパニオンオブジェクト内には任意の数のメソッド/プロパティを持つことができます。
コンパニオンオブジェクト内でlateinit変数を初期化できますか?
いいえ、constまたはコンパニオンオブジェクト内の変数はすぐに初期化されるか、明示的に初期化されるval/varでなければなりません。 lateinitはコンパニオンオブジェクト内のプロパティには許可されていません。
コンパニオンオブジェクトは独自の名前を持つことができ、いつそれが必要ですか?
はい、名前を指定することで、名前でアクセスしたり、インターフェースを実装したりすることができます。他の場合はオプションです。 例:
class Foo { companion object Factory { fun create(): Foo = Foo() } } val instance = Foo.Factory.create()
プログラムのすべての補助機能とグローバル変数がコンパニオンオブジェクトに配置され、varがval/constの代わりに使用される:
利点:
欠点:
コンパニオンオブジェクト内でcompilation-time定数(const val)とpure functionのみを使用し、すべての変更可能なものはローカライズされるか、DIを介して渡される:
利点:
欠点: