好程序員大數據學習路線爲大家分享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") }