クラスのコンパニオン オブジェクト (シングルトン) が必要な場合はありますか? Foo
クラスを作成し、そのコンパニオン オブジェクトも作成する必要があるのはなぜでしょうか。
7 に答える
コンパニオン オブジェクトは基本的に、「静的な」メソッドを配置できる場所を提供します。さらに、コンパニオン オブジェクトまたはコンパニオン モジュールは、プライベートなものを含むクラス メンバーへのフル アクセスを持ちます。
コンパニオン オブジェクトは、ファクトリ メソッドなどをカプセル化するのに最適です。たとえば、どこでも持つ必要がある代わりに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(/ ... /)という名前を付けると、クラスを作成/初期化できるようになります
'new'なし(それほど重要ではありません)
可能なパラメーターのセットが異なる(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とは呼びません。これは、抽象的なものを作成するような、見た目が悪くないためです。それらの名前に本当の意味を与えてください。不変、メソッドレス、ケースクラスの使用を検討し、抽象基本クラスをシールします。
Saem が彼の返信で述べたことに加えて、Scala コンパイラーは、対応するコンパニオン オブジェクト (ソースまたはターゲットのいずれか) で型の暗黙的な変換も検索するため、変換をインポートする必要はありません。
一般的なシングルトン オブジェクトの理由についてScala でのプログラミングは次のように述べています。
第 1 章で述べたように、Scala が Java よりもオブジェクト指向である理由の 1 つは、Scala のクラスが静的メンバーを持つことができないことです。代わりに、Scala にはシングルトン オブジェクト (p. 65) があります。