クラスのコンパニオンオブジェクト(シングルトン)が必要な場合はありますか?なぜクラスを作成し、そのクラスFoo
のコンパニオンオブジェクトも作成したいのですか?
クラスのコンパニオンオブジェクト(シングルトン)が必要な場合はありますか?なぜクラスを作成し、そのクラスFoo
のコンパニオンオブジェクトも作成したいのですか?
回答:
コンパニオンオブジェクトは、クラスのすべてのインスタンスに共通の状態とメソッドを格納するのに役立ちますが、静的メソッドやフィールドは使用しません。これらは、継承によってオーバーライドできる通常の仮想メソッドを使用します。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(/ ... /)という名前を付けると、クラスを作成/初期化できるようになります
「新しい」なし(それほど重要ではない)
可能なパラメーターの異なるセットを使用して(コンストラクターの伸縮についてBlochがEffective Javaで書き込んだものと比較してください)
抽象(伴奏)クラスの代わりに、作成する派生クラスを決定する機能
コード例:
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と呼んではいけません。それらの名前に本当の意味を与えてください。不変、メソッドレス、caseクラスの使用を検討し、抽象基本クラスをシールしてください。
RealThing
また、AlternativeThing
クラスにはprivate
、ユーザーAbstractClass
がhasファクトリを使用するように強制するコンストラクターが必要です。class AlternativeThing private(i: Int) extends AbstractClass
Saemが彼の返答で述べたことに加えて、Scalaコンパイラーは、対応するコンパニオンオブジェクト(ソースまたはターゲットのいずれか)の型の暗黙的な変換も検索するため、変換をインポートする必要はありません。
一般的に、シングルトンオブジェクトの理由についてスカラ座でのプログラミング言います:
第1章で述べたように、ScalaがJavaよりもオブジェクト指向である1つの方法は、Scalaのクラスが静的メンバーを持つことができないことです。代わりに、Scalaにはシングルトンオブジェクト(p。
私はコンパニオンオブジェクトを、Scalaで関数型とオブジェクト指向の両方のコードを記述するための橋渡しとして常に見ています。多くの場合、入力を受け取り、処理結果を提供する純粋な関数が必要です。これらの関連する関数をコンパニオンオブジェクトに配置することで、自分自身とコードの上に構築されたいくつかの人にとって、検索と使用が簡単になります。
また、何もせずにシングルトンパターンを書くための言語提供機能です。これは、JVMの存続期間にわたって委任者をカプセル化するシングルトンが必要な場合に特に役立ちます。たとえば、Scalaで単純なHTTPクライアントライブラリを作成すると、基盤となるJava実装ベースのデリゲーターをカプセル化して、APIのコンシューマーに純粋な世界で生活させることができます。
クラスとオブジェクトを同じ名前で同じファイルに定義する場合、それらはコンパニオンクラスとオブジェクトと呼ばれます。Scalaには、JAVAキーワードとしてstaticがありません。Scalaでは、静的クラスをコンパニオンクラスとオブジェクトで置き換えることができます。
詳細については、Scalaプログラミングの記事クラスとオブジェクトキーワードを確認してください。