2011-06-30 88 views
31

我得到的編碼是基本上提供了「對象SomeClass」和「類SomeClass」,伴隨類是類聲明,對象是singleton。其中你不能創建一個實例。所以......我的問題主要是在這個特定實例中單例對象的目的。Scala中單例對象的解釋

這基本上只是一種在Scala中提供類方法的方法嗎?像+基於Objective-C的方法?

我正在閱讀Programming in Scala這本書,第4章只講了單身物件,但沒有詳細說明爲什麼這很重要。

我意識到我可能會在這裏領先於自己,並且可能會在稍後詳細解釋。如果是這樣,讓我知道。這本書到目前爲止還是相當不錯的,但它有很多「用Java編寫,你這樣做」,但是我的Java經驗很少,所以我錯過了一些我害怕的點。我不希望這是其中的一種情況。

我不記得在那Programming in Scala website Java是閱讀本書的先決條件隨時隨地閱讀...

+0

實際上,作者聲稱Java並不是先決條件,但他們也評論說它比較有用。在第二版[Scala編程](http://www.artima.com/shop/programming_in_scala_2ed)中介紹:「另一方面,不需要編程語言的具體知識。儘管大多數人使用Scala在Java平臺上,本書並不假定您對Java有任何瞭解,但我們希望很多讀者熟悉Java,因此有時我們會將Scala與Java進行比較,以幫助讀者理解這些差異。「 Odersky等人(2008 [2010]:xlv))。 –

回答

50

是的,伴侶單例提供了與Java(和C++,c#等)靜態方法等價的方法。

然而,單身超越這個公平的方式(事實上,伴隨對象的方法是通過「靜態代理」的Java互操作的緣故暴露)。

  • 單例可以從其他類/特徵繼承方法,這是靜態不能完成的。
  • 一個單可以作爲參數(可能通過一個繼承的接口)
  • 一個單可以在周圍類或方法的範圍內存在,正如Java可以具有內部類
  • 另外值得一提的是,被傳遞單身人士並不一定是伴侶,在定義單身人士時沒有定義伴侶類是完全有效的。

這有助於使斯卡拉認爲的Java(靜態方法不屬於一個對象)一個更加面向對象的語言。具有諷刺意味的是,它主要是根據其功能性證書進行討論的。

+0

我剛剛在另一個線程中發佈了一個指向[您的答案]的鏈接(http://stackoverflow.com/questions/4112088/why-are-singleton-objects-more-object-orientated/4112864#4112864) 。尼斯的精神力量。 –

+0

你知道嗎,我簡直忘了! –

+0

謝謝,真棒回答。欣賞它。 – gks

2

是的,它基本上是作爲一個伴侶對象使用時提供class methods的一種方式。

13

在很多情況下,我們需要一個單例來代表我們的軟件系統中的獨特對象。 想想太陽系吧。我們可能有如下班

class Planet 
object Earth extends Planet 
object Sun extends Planet 

對象是一個簡單的方法來創建單,當然它通常用來創建一流水平的方法,如靜態方法在Java中

+1

+1通過您的示例選擇暗示與Java枚舉相當...... –

4

附加給定答案(中去在與jilen相同的總體方向上),object在Scala的implicit機制中發揮重要作用,例如允許類級類似的行爲(從哈斯克爾知道):

trait Monoid[T] { 
    def zero:T 
    def sum(t1:T, t2:T):T 
} 

def fold[T](ts:T*)(implicit m:Monoid[T]) = ts.foldLeft(m.zero)(m.sum(_,_)) 

現在我們有一個fold - 功能。只要有合適的Monoid(具有中性元素,並且可以「以某種方式加在一起」的形式)「合併」多個T。爲了利用這一點,我們需要一個Monoid只有一個例如針對某些類型的T,爲object完美的工作:

implicit object StringMonoid extends Monoid[String] { 
    def zero = "" 
    def sum(s1:String, s2:String) = s1 + s2 
} 

現在這個工程:

println(fold("a","bc","def")) //--> abcdef 

所以object s爲在他們自己的權利非常有用。

但等等,還有更多!擴展他們的同伴類時同伴對象也可以作爲一種「默認配置」的:你有特質Config,這可以通過但她想要的用戶來實現,一方面

trait Config { 
    def databaseName:String 
    def userName:String 
    def password:String 
} 

object Config extends Config { 
    def databaseName = "testDB" 
    def userName = "scott" 
    def password = "tiger" 
} 

左右,但另一方面,當您想要使用默認設置時,有一個現成的對象Config

+1

我不明白此答案 – Valentin

+3

@Valentin Vasilyev我很抱歉聽到這個消息,但我無法解釋這裏的所有細節,所以我只是掠過了一些用例。有詳細的處理這些東西的優秀教程,尤其是隱式機制是一個非常有用和多用途的工具,但需要對不同情況進行大量的解釋。 – Landei