使用new運算符定義對象與通過擴展類定義獨立對象之間的區別是什麼?斯卡拉 - 新的vs對象擴展
更具體而言,給定類型class GenericType { ... }
,val a = new GenericType
和object a extends GenericType
之間的區別是什麼?
使用new運算符定義對象與通過擴展類定義獨立對象之間的區別是什麼?斯卡拉 - 新的vs對象擴展
更具體而言,給定類型class GenericType { ... }
,val a = new GenericType
和object a extends GenericType
之間的區別是什麼?
作爲一個實際問題,object
聲明初始化爲相同的機制如在字節碼new
。但是,有很多不同之處:
object
作爲單例 - 每個屬於只有一個實例存在的類;object
被延遲初始化 - 它們只會在首次引用時被創建/初始化;object
和class
(或trait
)的相同名稱是伴侶;object
上的方法在伴侶class
上生成靜態轉發器;object
的成員可以訪問夥伴class
的私人成員;這些只是我能想到的蝙蝠權利的一些差異。可能還有其他人。
*什麼是「相關」類或性狀是一個更長的故事 - 查找堆棧溢出問題,如果你有興趣解釋它。如果您無法找到它們,請查看scala
標記的維基。
對象定義(無論它是否擴展)意味着創建單例對象。
scala> class GenericType
defined class GenericType
scala> val a = new GenericType
a: GenericType = [email protected]
scala> val a = new GenericType
a: GenericType = [email protected]
scala> object genericObject extends GenericType
defined module genericObject
scala> val a = genericObject
a: genericObject.type = [email protected]
scala> val a = genericObject
a: genericObject.type = [email protected]
雖然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與Foo
新實例初始化,而test2
b
定義爲一個object
延伸Foo
。 實質上,它們都會懶惰地創建一個Foo
的新實例併爲其命名(a
/b
)。
,您可以嘗試在REPL並驗證它們都具有相同的行爲:由語言
scala> test1()
a.new
a.doSomething(1)
a.doSomething(2)
scala> test2()
b.new
b.doSomething(1)
b.doSomething(2)
所以儘管object
和lazy val
之間的語義差異(尤其是特殊處理的object
的,如Daniel C.所述Sobral), a lazy val
總是可以用相應的object
代替(這不是一種非常好的做法),同樣也適用於屬於類/特徵成員的lazy val
/object
。 我能想到的主要實際區別是對象具有更具體的靜態類型:b
類型爲b.type
(它擴展了Foo
),而a
恰好類型爲Foo
。
lazy val a:Foo =一個 – 2014-07-11 10:52:55
可能重複[val和對象在scala類內?](http://stackoverflow.com/questions/3448691/val-and-object-inside-a-scala-class) – Bergi 2016-05-25 04:00:25