好程式設計師大資料學習路線分享Scala系列之物件
1. 單例物件
在Scala中沒有靜態方法和靜態欄位,但是可以使用object這個語法結構來達到同樣的目的
1.scala類似於Java中的工具類,可以用來存放工具函式和常量
2.高效共享單個不可變的例項
3.單例模式
單例物件雖然類似於Java中的工具類,但它不是,還是一個物件,可以把單例物件名看做一個貼在物件上的標籤。
package logging
//使用關鍵字object定義單例物件
object Logger {
def info(message: String): Unit = println(s"INFO: $message"
}
單例物件的使用
//匯入單例物件資訊,使之在當前類可見
import logging.Logger.info
class Project(name: String, daysToComplete: Int)
class Test {
val project1 = new Project("TPS Reports", 1)
val project2 = new Project("Website redesign", 5)
//呼叫單例物件中定義的方法
info("Created projects") // Prints "INFO: Created projects"
}
類和單例物件的區別是,單例物件不能帶引數,單例物件不能用new關鍵字例項化,所以沒有機會傳遞給它例項化的引數。
單例物件在第一次訪問的時候才會初始化。
當單例物件與某個類同名時,它被稱為類的伴生物件,類和伴生物件必須定義在一個原始檔裡,類稱為該單例物件的伴生類,類和他的伴生物件可以互相訪問其私有成員。
不與伴生類共享名稱的單例物件被稱為獨立物件,可以作為相關功能的工具類,或者scala應用程式的入口點。
2. 伴生物件
在Scala的類中,與類名相同並且用object修飾的物件叫做伴生物件,類和伴生物件之間可以相互訪問私有的方法和屬性,他們必須存在同一個原始檔中
class AccountInfo {
//類的伴生物件的功能特性並不在類的作用域
//所以不能直接用newUniqueNumber()呼叫伴生物件的方法
var id = AccountInfo.newUniqueNumber()
}
object AccountInfo {
private var lastNumber = 0
private def newUniqueNumber() = {
lastNumber += 1; lastNumber
}
def main(args: Array[String]) {
//相當於Java中的靜態方法呼叫
println(AccountInfo.newUniqueNumber())
}
}
3. apply方法
通常我們會在類的伴生物件中定義apply方法,當遇到類名(引數1,...引數n)時apply方法會被呼叫
class AccountInfo {
}
object AccountInfo {
private var lastNumber = 0
private def apply(arg :Int) = {
lastNumber = arg*2 + 1; lastNumber
}
def main(args: Array[String]) {
println(AccountInfo(1))
}
}
4. 應用程式物件
Scala程式都必須從一個物件的main方法開始,可以通過擴充套件App特質,不寫main方法。
object Hello extends App{
println("Hello World")
}
同
object Hello {
def main(args: Array[String]): Unit = {
println("Hello World")
}
}
5.提取器
帶有unapply方法的物件,經常用在模式匹配或者偏函式中。
import scala.util.Random
object CustomerID {
def apply(name: String) = s"$name--${Random.nextLong}"
def unapply(customerID: String): Option[String] = {
val name = customerID.split("--").head
if (name.nonEmpty) Some(name) else None
}
}
//呼叫apply方法建立一個物件,等價於CustomerID.apply("Sukyoung")
val customer1ID = CustomerID("Sukyoung") // Sukyoung--23098234908
customer1ID match {
//呼叫unapply方法,提取name資訊
case CustomerID(name) => println(name) // prints Sukyoung
case _ => println("Could not extract a CustomerID")