1. 程式人生 > >Scala 單例物件

Scala 單例物件

單例物件

物件是隻有一個例項的類。當它被引用時,它會被怠慢建立,就像lazy val一樣。
作為頂層值,物件是單例。
作為一個封閉類的成員或本地值,它的行為與lazy val完全相同。

1 定義單例物件

一個物件是一個值。物件的定義類似class,但是使用關鍵字object。

# 定義物件
object Box

# 定義物件(具有方法)
object Logger {
  def info(message: String): Unit = println(s"INFO: $message")
}

2 引用物件

import logging.Logger.info

class Project(name: String, dayToComplete: Int)
class Test{
  val project1 = new Project("TPS Reports", 1)
  val project2 = new Project("Website redesign", 5)
  info("Created projects")
}

note:通過import語句,info方法可見。
ps:引入需要被引入符號的可靠路徑,物件為可以作為可靠路徑。
ps:如果一個物件並非位於頂層,而是巢狀於其他的類或物件中,那麼,這個物件將和其他成員一樣,是“路徑依賴”的。

3 伴侶物件

與類同名的物件稱之為伴侶物件。與之對應,類為物件的伴侶類。伴侶物件或伴侶類可以訪問其伴侶的私有成員。對於伴侶類的例項而言,用於伴侶物件的方法與值並非是特定的。

import scala.math._

# 定義伴侶類
case class Circle(radius: Double) {
  import Circle.calculateArea
  def area: Double = calculateArea(radius)
}

# 定義伴侶物件
object Circle {
  private def calculateArea(radius: Double):Double = Pi * pow(radius, 2.0)
}

note:Circle類成員area非單例,Circle物件的方法calculateArea是單例,每個例項皆可使用。

伴侶物件包含工廠方法

class Email(val username: String, val domainName: String)

object Email{
  def fromString(emailString:String): Option[Email] = {
    emailString.split('@')match {
      case Array(a, b) => Some(new Email(a, b))
      case _ => None
    }
  }

如果類或物件具有伴侶,它們就必須位於同一個檔案中。

4 注意

Java中的靜態成員在Scala中被建模為伴侶物件的普通成員。
當使用Java程式碼中的伴隨物件時,定義在伴隨類中的成員需要帶有static修飾語。這被稱為靜態轉發。即使沒有在伴隨類中定義,也會出現。