Scala学习笔记之单例对象Singleton Objects
如果某个方法或域与某个类的特定对象无关,而是只与类相关,把它归于单例对象singleton objects
,即由object
关键字声明的类型:
object X {
val n = 2;
def f = n * 10
}
对单例对象,正如它的名字所说明的,它就是单例的,使用的时候,不需要new
,直接调X.f
即可得到返回值20,对Java程序猿来说,这不就是static
的作用吗?是的,在Scala中,所有原本Java中用static
修饰的属性和方法或者代码块都应该移到单例对象里。
单例对象可以扩展类和接口。
单例对象有些时候是作为伴随对象companion object
出现的,即它是另一个同名类的伴随对象,我们称其中的class
为伴随类,object
为伴随对象。伴随类和它的伴随对象需要定义在同一个文件里,它们的关系是Friendly
,即可以互相访问对方的私有方法或域,如果不想被对方访问,需要用private[this]
来修饰。伴随对象访问伴随类示例代码如下:
class A {
private val fieldB = 10
// bar是完全私有的,不可从外部访问
private[this] def bar:Int = fieldB * 5
}
object A {
def foo:Int = (new A).fieldB * 5
}
伴随类访问伴随对象示例代码如下:
class A {
private val fieldB = 10
def bar:Int = A.foo
}
object A {
def foo:Int = (new A).fieldB * 5
}
伴随对象的一种常见应用就是case类,没有类型参数的case类会被自动创建一个伴随对象,这个对象实现Function*
接口的apply
方法,当伴随对象的名字后面有圆括号时,Scala就会调用apply
方法。模拟代码如下:
class Car(val make:String) {
override def toString = s"Car($make)"
}
object Car {
def apply(make:String) = new Car(make)
}
val myCar = Car("BMW")
是不是跟case类用起来一样?将它扩展一下,就可以方便的变成工厂模式,这也是单例对象的常见用法。