Singleton 伴随对象

单例对象

Scala 支持静态成员,但与 Java 不同。Scala 提供了一种替代方法,称为 Singleton Objects 。Singleton 对象类似于普通类,除非它们不能使用 new 关键字进行实例化。下面是一个单例类示例:

object Factorial {
    private val cache = Map[Int, Int]()
    def getCache = cache
}

请注意,我们使用 object 关键字来定义单个对象(而不是’class’或’trait’)。由于单例对象无法实例化,因此无法使用参数。访问单个对象如下所示:

Factorial.getCache() //returns the cache

请注意,这看起来与访问 Java 类中的静态方法完全相同。

伴侣对象

在 Scala 中,单例对象可以共享相应类的名称。在这种情况下,单例对象称为伴随对象。例如,在类下面定义了 Factorial,并在其下面定义了一个伴随对象(也称为 Factorial)。按照惯例,伴随对象在与其伴随类相同的文件中定义。

class Factorial(num : Int) {

  def fact(num : Int) : Int = if (num <= 1) 1 else (num * fact(num - 1))

  def calculate() : Int = {
    if (!Factorial.cache.contains(num)) {    // num does not exists in cache
      val output = fact(num) // calculate factorial
      Factorial.cache += (num -> output)     // add new value in cache
    }

    Factorial.cache(num)
  }
}

object Factorial {
  private val cache = scala.collection.mutable.Map[Int, Int]()
}

val factfive = new Factorial(5)
factfive.calculate  // Calculates the factorial of 5 and stores it
factfive.calculate  // uses cache this time
val factfiveagain = new Factorial(5)
factfiveagain.calculate  // Also uses cache

在这个例子中,我们使用私有 cache 来存储数字的阶乘,以节省重复数字的计算时间。

这里 object Factorial 是一个伴侣对象,class Factorial 是它的对应伴侣类。伴随对象和类可以访问彼此的 private 成员。在上面的例子中,Factorial 类正在访问它的伴随对象的私有 cache 成员。

请注意,类的新实例化仍将使用相同的伴随对象,因此对该对象的成员变量的任何修改都将继承。