7

new 演算子を使用してオブジェクトを定義することと、クラスを拡張してスタンドアロン オブジェクトを定義することの違いは何ですか?

より具体的には、 type が与えられた 場合、 とclass GenericType { ... }の違いは何ですか?val a = new GenericTypeobject a extends GenericType

4

3 に答える 3

10

実際問題として、宣言はバイトコードobjectと同じメカニズムで初期化されます。newただし、いくつかの違いがあります。

  • objectシングルトンとして -- それぞれは、インスタンスが 1 つだけ存在するクラスに属します。
  • object遅延初期化されます-最初に参照されたときにのみ作成/初期化されます。
  • 同じ名前のanobjectと a class(またはtrait) はコンパニオンです。
  • で定義されたメソッドobjectは、コンパニオンで静的フォワーダーを生成しますclass
  • のメンバーはobject、コンパニオンのプライベート メンバーにアクセスできますclass
  • 暗黙を検索するとき、関連する*クラスまたは特性のコンパニオンオブジェクトが調べられます。

これらは、私がすぐに思いつく違いのほんの一部です。おそらく他にもあります。

* 「関連する」クラスまたは特性とは長い話です。興味がある場合は、それについて説明している Stack Overflow の質問を調べてください。scalaタグが見つからない場合は、Wiki でタグを参照してください。

于 2013-04-24T04:20:34.830 に答える
5

オブジェクト定義 (何かを拡張するかどうかにかかわらず) は、シングルトン オブジェクトの作成を意味します。

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
于 2013-04-24T04:05:13.137 に答える
2

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

于 2013-04-24T10:29:51.470 に答える