Scala学习之类和属性篇(三):单例与私有构造函数

咱们知道,要想使用单例那么就必须定义私有构造函数来防止从类的外部来建立类的实例。在Scala中你也能够经过private关键字定义类的私有主构造函数来防止从类的外部建立类的实例。函数

scala> class Person private(name: String)
defined class Person
warning: previously defined object Person is not a companion to class Person.
Companions must be defined together; you may wish to use :paste mode for this.

scala> val p = new Person("Ming")
<console>:12: error: constructor Person in class Person cannot be accessed in object $iw
       val p = new Person("Ming")
               ^

咱们看到在类的外部已经没法使用new关键字来实例化这个类了。那么在Scala中如何实现getInstance方法来获取这个对象的实例呢,就是在类的伴生对象中实现这个方法。this

scala> :paste
// Entering paste mode (ctrl-D to finish)

class Person private(name: String)

object Person {
  def getInstance(name: String) = new Person(name)
}

// Exiting paste mode, now interpreting.

defined class Person
defined object Person

scala> val p = Person.getInstance("Ming")
p: Person = Person@7859bd9a

你可能发现了,这个时候Person并非一个单例对象,而只是限制了主构造函数的访问权限。其实在Scala中实现一个单例对象最简单的方式就是直接使用类的伴生对象,而不须要定义类。固然你也能够像Java中那样去实现一个单例对象。你会看到无论你调用多少次getInstance方法,获得的都是同一个对象。scala

scala> :paste
// Entering paste mode (ctrl-D to finish)

class Person private(name: String)

object Person {
  private var p:Option[Person] = None
  def getInstance(name: String): Person = {
    if (!p.isDefined) {
      p = Some(new Person(name))
    } 
    p.get
  }
}

// Exiting paste mode, now interpreting.

defined class Person
defined object Person

scala> val p = Person.getInstance("Ming")
p: Person = Person@47d32e33

scala> val p = Person.getInstance("Li")
p: Person = Person@47d32e33
相关文章
相关标签/搜索