質問

クラスのコンパニオンオブジェクト(シングルトン)が必要な場合はありますか? Foo と言うクラスを作成し、そのクラスのコンパニオンオブジェクトも作成するのはなぜですか?

役に立ちましたか?

解決

コンパニオンオブジェクトは基本的に、「静的な」部分を配置できる場所を提供します。メソッド。さらに、コンパニオンオブジェクトまたはコンパニオンモジュールは、プライベートメンバーを含むクラスメンバーへのフルアクセスを持ちます。

コンパニオンオブジェクトは、ファクトリメソッドなどをカプセル化するのに最適です。たとえば、 Foo FooFactory をどこにでも持たせる代わりに、コンパニオンオブジェクトを持つクラスにファクトリーの責任を持たせることができます。

他のヒント

コンパニオンオブジェクトは、クラスのすべてのインスタンスに共通の状態とメソッドを保存するのに役立ちますが、静的/強いメソッドまたはフィールドを使用しません。これらは、継承によってオーバーライドできる通常の仮想メソッドを使用します。 Scalaには静的なものは何もありません。これを使用する方法はたくさんありますが、ここに簡単な例を示します。

abstract class AnimalCounter
{
    var animals = 0

    def name: String

    def count()
    {
        animals += 1
        println("%d %ss created so far".format(animals, name))
    }
}

abstract class Animal
{
    def companion: AnimalCounter
    companion.count()
}

object Dog extends AnimalCounter
{
    val name = "dog"
}

class Dog extends Animal
{
    def companion = Dog
}

object Cat extends AnimalCounter
{
    val name = "cat"
}

class Cat extends Animal
{
    def companion = Cat
}

次の出力が生成されます:

scala> new Dog
1 dogs created so far

scala> new Cat
1 cats created so far

scala> new Dog
2 dogs created so far

scala> new Cat
2 cats created so far

...そして、付随するクラスの静的ファクトリーメソッド(DPではありません)を保存するのに適した場所です。これらのオーバーロードされたファクトリメソッドにapply(/ ... /)という名前を付けると、クラスを作成/初期化できます

  1. 「new」なし(それほど重要ではない)

  2. 可能なパラメータの異なるセット(Blochがテレスコープコンストラクターについて効果的なJavaで書いたものと比較してください)

  3. 抽象(付属)クラスの代わりに作成する派生クラスを決定する機能を備えています

サンプルコード:

abstract class AbstractClass;
class RealThing(s: String) extends AbstractClass;
class AlternativeThing(i: Int) extends AbstractClass;
object AbstractClass {
  def apply(s: String) = {
    new RealThing(s)
  }
  def apply(i: Int) = {
    new AlternativeThing(i)
  }
}

// somewhere else you can
val vs = AbstractClass("asdf")  // gives you the RealThing wrapped over string
val vi = AbstractClass(123)  // gives you AlternativeThing wrapped over int

見た目が悪くないため、オブジェクト/ベースクラスのAbstractXxxxxを呼び出しません。抽象的なものを作成するようなものです。それらの名前に本当の意味を与えてください。 不変、メソッドレス、ケースクラスの使用を検討し、抽象基本クラスを封印します。

彼の返信、Scalaコンパイラーは暗黙的な変換も検索します(ソースまたはターゲットの)対応するコンパニオンオブジェクトの型であるため、変換をインポートする必要はありません。

シングルトンオブジェクトの一般的な理由について Scalaでのプログラミングは次のように述べています。

  

第1章で述べたように、ScalaがJavaよりもオブジェクト指向である1つの方法は、Scalaのクラスが静的メンバーを持つことができないことです。代わりに、Scalaにはシングルトンオブジェクトがあります(p。65)。

コンパニオンオブジェクトは、Scalaで機能コードとオブジェクト指向コードの両方を記述するためのブリッジであると常に考えています。多くの場合、何らかの入力を受け取り、処理結果を提供する純粋な関数が必要です。これらの関連する関数をコンパニオンオブジェクトに配置すると、自分とコードの上に構築された誰かのために、簡単に検索して使用できます。

さらに、何もせずにシングルトンパターンを記述するための言語提供機能です。これは、JVMの存続期間中に委任者をカプセル化するためにシングルトンが必要な場合に特に役立ちます。たとえば、Scalaで簡単なHTTPクライアントライブラリを作成します。このライブラリでは、基になるJava実装ベースの委任者をカプセル化し、APIのコンシューマーを純粋な世界で使用できます。

クラスとオブジェクトを同じ名前で同じファイルに定義する場合、それらはコンパニオンクラスとオブジェクトとして知られています。 ScalaにはJAVAキーワードとしてstaticがありません。Scalaのstaticをコンパニオンクラスおよびオブジェクトに置き換えることができます。

詳細については、記事をご覧ください scalaプログラミングのクラスおよびオブジェクトキーワード

最初は、静的メソッドと非静的メソッドの明確な分離を提供します。また、シングルトンクラスを作成する簡単な方法も提供します。

他のクラスやトレイトからメソッドを継承することもできますが、これはJavaの静的メソッドでは実行できず、パラメーターとして渡すことができます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top