web-dev-qa-db-ja.com

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

Scalaにはstatic-keywordはありませんが、代わりにコンパニオンオブジェクトを通じて同様の機能があります。背後では、コンパニオンオブジェクトが静的メソッドを持つクラスにコンパイルされているため、これらはすべて構文上の砂糖です。この設計の選択の利点は何ですか?短所?他の言語は同様の構成要素を持っていますか?

51
Zavior

自分の好みに応じて、多かれ少なかれ説得力のある理由がいくつかあります。

  1. 「構文上の砂糖」であると単純に割り引いてはいけません。あなたは何かがjust構文上の砂糖であると言うかもしれませんが、あなたの人生を甘くするのは結局のところ砂糖です-プログラマーとしてだけでなく、コーヒーやお茶を飲む人として。

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

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

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

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

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

52
Frank

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

36
Alexey Romanov

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

Java devでJava言語またはライブラリが同等のメカニズムを提供しているかどうかを知るには十分ではありません。

5
Gene T