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 成員。

請注意,類的新例項化仍將使用相同的伴隨物件,因此對該物件的成員變數的任何修改都將繼承。