Scalaのコンパニオンオブジェクトと静的メソッドの利点は何ですか?


50

Scalaには静的なキーワードはありませんが、代わりにコンパニオンオブジェクトを通じて同様の機能があります。舞台裏では、コンパニオンオブジェクトは静的メソッドを持つクラスにコンパイルされるため、これはすべて構文糖です。この設計選択の利点は何ですか?欠点?他のラングアンジュには同様の構造がありますか?


回答:


49

ここにいくつかの理由がありますが、あなた自身の好みに応じて、多かれ少なかれ説得力があるかもしれません。

  1. 「シンタックスシュガー」であることで単純に値引きしないでください。あなたは何かが単なる構文糖質であると言うかもしれませんが、それは結局、あなたの人生を甘くする糖分です-ちょうどコーヒーまたはお茶を飲む人としてだけでなく、プログラマーとして。

  2. シングルトン-すべてのScala objectは本質的にシングルトンです。Javaの世界では、さまざまな方法でシングルトンを実装しているため、実装に何らかの間違いを犯すことが多いため、Scalaのような単純なエラーを作成することはできません。object代わりに書くことはclassそれをシングルトンにし、完了です。

  3. 静的メソッドへのアクセス:Javaの静的メソッドには、オブジェクトからアクセスできます。たとえばC、静的メソッドfctypeのオブジェクトを持つクラスがあるとしますC。次にを呼び出す必要C.fがありますが、Javaでは(警告はありますが)を使用できます。c.fオブジェクトにはメソッドがないため、Scalaのバックグラウンドから来たときに意味がありませfん。

  4. 明確な分離:Javaでは、クラス内で静的属性と非静的属性およびメソッドを混在させることができます。規律を持って作業すれば、これは問題になりませんが、あなた(または他の誰か)がそうしなければ、静的な部分と非静的な部分が交互に配置されることになり、一目でわかりにくくなります静的なものとそうでないもの。Scalaでは、コンパニオンオブジェクト内にあるすべてのものは、対応するクラスのランタイムオブジェクトの一部ではありませんが、静的コンテキストから利用できます。逆に、クラス内で記述されている場合、そのクラスのインスタンスで使用できますが、静的コンテキストからは使用できません。これは、クラスに静的および非静的初期化子ブロックを追加し始めると、Javaで特に負担になります。これは、動的な実行順序の観点から理解するのが非常に困難になる可能性があります。

  5. 少ないコード:のすべての属性またはメソッドにstaticという単語を追加する必要がないためobject、コードをより簡潔に保つことができます(実際、顕著な利点ではありません)。

欠点を見つけるのははるかに困難です。静的部分と非静的部分は一緒に属するべきであるが、コンパニオンオブジェクトのScalaコンセプトによって分離されていると主張するかもしれません。たとえば、クラス図があるのは奇妙に見えるかもしれませんが、コードで2つのものを作成し、どの属性がどこに行くかを分析する必要があります。


1
また、静的は純粋なOOPソフトウェアに属していないと読みました。同様に、静的な振る舞いが必要な場合は、独自のクラスを使用して、その(単一の)オブジェクトを作成し、別のクラスのオブジェクトの(潜在的に)静的な振る舞いを管理します。
K ..

1
「クラスの代わりにオブジェクトを記述すると、それがシングルトンになり、完了です。」私はシングルトンをあまり気にしませんが、この特定の「構文糖」の直接性には特定の魅力があることを認めざるを得ません。
エドヘイスティングス

3
1から5までのポイント(およびそれらすべてを合わせて)のいずれも、実行時に真のコンパニオンオブジェクトを実装する必要はありません。それらはすべて、実行時の影響なしで、純粋な構文糖に簡単に作成できます。実行時のコンパニオンオブジェクトを持つ唯一の本当の理由は、Alexey Romanovの答えにあります。
mas.morozov

「欠点を見つけるのははるかに困難です。」パフォーマンス?オブジェクトメソッドにアクセスするifnonnullと、単にと比較してetcバイトコードが生成されますinvokeStatic
エドゥアルドパレハト

33

もう1つの利点は、object静的メソッドとは異なり、インターフェイス/特性を実装できることです。


8
これはコンパニオンオブジェクトと静的メソッドを持つクラス大きな違いだと思います。コンパニオンオブジェクトはポリモーフィックであり、インターフェイス/特性を期待するメソッドへの引数として渡すことができます。
dcastro

4

コンパニオンオブジェクトは、暗黙的に最初に検索される場所です。その後、scalaはPredefを調べ、その特定のソースファイルの明示的な「import」ステートメントを調べます。

私は、Java言語やライブラリが同等のメカニズムを提供しているかどうかを知るためのJava開発者ではありません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.