2011-06-30 54 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