new 演算子を使用してオブジェクトを定義することと、クラスを拡張してスタンドアロン オブジェクトを定義することの違いは何ですか?
より具体的には、 type が与えられた 場合、 とclass GenericType { ... }の違いは何ですか?val a = new GenericTypeobject a extends GenericType
new 演算子を使用してオブジェクトを定義することと、クラスを拡張してスタンドアロン オブジェクトを定義することの違いは何ですか?
より具体的には、 type が与えられた 場合、 とclass GenericType { ... }の違いは何ですか?val a = new GenericTypeobject a extends GenericType
実際問題として、宣言はバイトコードobjectと同じメカニズムで初期化されます。newただし、いくつかの違いがあります。
objectシングルトンとして -- それぞれは、インスタンスが 1 つだけ存在するクラスに属します。object遅延初期化されます-最初に参照されたときにのみ作成/初期化されます。objectと a class(またはtrait) はコンパニオンです。objectは、コンパニオンで静的フォワーダーを生成しますclass。object、コンパニオンのプライベート メンバーにアクセスできますclass。これらは、私がすぐに思いつく違いのほんの一部です。おそらく他にもあります。
* 「関連する」クラスまたは特性とは長い話です。興味がある場合は、それについて説明している Stack Overflow の質問を調べてください。scalaタグが見つからない場合は、Wiki でタグを参照してください。
オブジェクト定義 (何かを拡張するかどうかにかかわらず) は、シングルトン オブジェクトの作成を意味します。
scala> class GenericType
defined class GenericType
scala> val a = new GenericType
a: GenericType = GenericType@2d581156
scala> val a = new GenericType
a: GenericType = GenericType@71e7c512
scala> object genericObject extends GenericType
defined module genericObject
scala> val a = genericObject
a: genericObject.type = genericObject$@5549fe36
scala> val a = genericObject
a: genericObject.type = genericObject$@5549fe36
object宣言は式とは異なるセマンティックを持ちますが、newローカルobject宣言は、すべての意図と目的lazy valに対して、同じ名前の と同じものです。検討:
class Foo( name: String ) {
println(name+".new")
def doSomething( arg: Int ) {
println(name+".doSomething("+arg+")")
}
}
def bar( x: => Foo ) {
x.doSomething(1)
x.doSomething(2)
}
def test1() {
lazy val a = new Foo("a")
bar( a )
}
def test2() {
object b extends Foo("b")
bar( b )
}
test1の新しいインスタンスでa初期化された遅延 val として定義し、拡張する として定義します。本質的には、 の新しいインスタンスを遅延して作成し、それに名前 ( / ) を付けます。Footest2bobjectFooFooab
REPL で試して、両方が同じように動作することを確認できます。
scala> test1()
a.new
a.doSomething(1)
a.doSomething(2)
scala> test2()
b.new
b.doSomething(1)
b.doSomething(2)
objectしたがって、と aのセマンティックの違いにもかかわらずlazy val(特に、objectDaniel C. Sobral によって概説されているように、言語による 's の特別な扱い)、 alazy valは常に対応する a に置き換えることができますobject(それは非常に良い習慣ではありません)。クラス/特性のメンバーであるlazy val/についても同じことが言えます。object私が考えることができる主な実際的な違いは、オブジェクトがより具体的な静的タイプをb持っていることです。b.typeFooaFoo