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

大兔子大兔子 提交于 2020-03-12 21:46:27

我们知道,要想使用单例那么就必须定义私有构造函数来防止从类的外部来创建类的实例。在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方法来获取这个对象的实例呢,就是在类的伴生对象中实现这个方法。

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> :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

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!