柚子快報(bào)激活碼778899分享:8 scala的伴生對象
1 單例對象
在編寫 Java 程序時,我們經(jīng)常會通過編寫靜態(tài)方法代碼,去封裝常用的 Utility 類。
在 Scala 中沒有靜態(tài)成員這一概念,所以,如果我們要定義靜態(tài)屬性或方法,就需要使用 Scala 的單例對象 object。Scala 的對象跟 Javascript 中定義一個對象,概念是差不多的。
下面定義一個球員對象,并在 main 函數(shù)打印球員對象的相關(guān)屬性:
/**
* 球員對象
*/
object FootballPlayerObject {
/**
* 姓名
*/
var NAME: String = "Mohamed Salah"
/**
* 年紀(jì)
*/
var AGE: Int = 31
/**
* 所在俱樂部
*/
var CLUB: String = "Liverpool"
/**
* 定義入口 main 函數(shù),打印球員對象相關(guān)屬性
* @param args
*/
def main(args: Array[String]): Unit = {
System.out.println(FootballPlayerObject.NAME)
System.out.println(FootballPlayerObject.AGE)
System.out.println(FootballPlayerObject.CLUB)
}
}
2 工具類案例
我們可以利用單例對象實(shí)現(xiàn)工具類,例如,下面實(shí)現(xiàn)了一個簡易的 DateUtils
import org.joda.time.format.DateTimeFormat
/**
* 日期時間工具類
*/
object DateUtils {
val TIME_FORMAT = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")
/**
* 判斷一個時間是否在另一個時間之前
*
* @param time1 第一個時間
* @param time2 第二個時間
* @return 判斷結(jié)果
*/
def before(time1: String, time2: String): Boolean = {
TIME_FORMAT.parseDateTime(time1).isBefore(TIME_FORMAT.parseDateTime(time2))
}
/**
* 判斷一個時間是否在另一個時間之后
*
* @param time1 第一個時間
* @param time2 第二個時間
* @return 判斷結(jié)果
*/
def after(time1: String, time2: String): Boolean = {
TIME_FORMAT.parseDateTime(time1).isAfter(TIME_FORMAT.parseDateTime(time2))
}
/**
* 計(jì)算時間差值(單位為秒)
*
* @param time1 時間1
* @param time2 時間2
* @return 差值
*/
def minus(time1: String, time2: String): Int = {
((TIME_FORMAT.parseDateTime(time1).getMillis - TIME_FORMAT.parseDateTime(time2).getMillis) / 1000).toInt
}
def main(args: Array[String]): Unit = {
println(DateUtils.before("2023-01-01 00:00:00", "2024-01-01 00:00:00"))
println(DateUtils.after("2023-01-01 00:00:00", "2024-01-01 00:00:00"))
println(DateUtils.minus("2024-01-01 00:00:00", "2023-01-01 00:00:00"))
}
}
運(yùn)行后,控制臺打?。?/p>
true
false
31536000
3 伴生對象
如果想一個類,既需要靜態(tài)成員,又需要實(shí)例成員,在 Scala 中可以使用伴生對象(companion object)來實(shí)現(xiàn)。
3.1 伴生對象的定義
伴生對象有以下特點(diǎn):
(1) 伴生對象 和 類 必須要在同一個 class 文件中。
(2) 伴生對象名字要和類名字一致。
(3) 伴生類 和 伴生對象可以互相訪問彼此的 private 屬性。
/**
* 球員信息類
*/
class PlayerInfo(private var playerName: String, var age: Int, var club: String) {
def hello(): String = {
s"Hey buddy, I am ${this.playerName} of ${this.club}, ${this.age} years old!"
}
}
/**
* PlayerInfo 類的共生對象
*/
object PlayerInfo {
/**
* 定義球員夢想
*/
private var dream: String = "The dream of %s is achieving World Cup"
/**
* 打印球員夢想
*/
def myDream(playerName: String): String = {
String.format(this.dream, playerName)
}
/**
* main 方法
* @param args
*/
def main(args: Array[String]): Unit = {
// 定義球員信息對象
val player: PlayerInfo = new PlayerInfo("Erling Haaland", 23, "Manchester City F.C.")
println(player.hello())
// 執(zhí)行共生對象的 myDream 方法
// 可以訪問共生類的私有 playerName
println(this.myDream(player.playerName))
}
}
3.2 apply 及 unapply 方法
在 Scala 中,apply 和 unapply 是兩個特殊的方法,它們通常與伴生對象一起使用,并且在模式匹配、構(gòu)造對象等方面發(fā)揮著重要作用。
3.2.1 apply 方法
apply 方法通常用于對象的構(gòu)造。當(dāng)你調(diào)用類似 ClassName(args) 的代碼時,實(shí)際上是調(diào)用了類的伴生對象的 apply 方法。這使得你可以像調(diào)用函數(shù)一樣構(gòu)造對象,而不需要顯式地使用 new 關(guān)鍵字。
例如,我們在定義一個列表時,并不需要使用 new: val list = List(1, 2, 3),下面為球員信息類的共生對象定義了 apply 方法:
/**
* 球員信息類
*/
class PlayerInfo(private var playerName: String, var age: Int, var club: String) {
def hello(): String = {
s"Hey buddy, I am ${this.playerName} of ${this.club}, ${this.age} years old!"
}
}
/**
* PlayerInfo 類的共生對象
*/
object PlayerInfo {
/**
* 定義球員夢想
*/
private var dream: String = "The dream of %s is achieving World Cup"
/**
* 打印球員夢想
*/
def myDream(playerName: String): String = {
String.format(this.dream, playerName)
}
/**
* 定義 apply 方法,新建一個 PlayerInfo 對象
*
* @param playerName 球員名稱
* @param age 年齡
* @return {@link PlayerInfo} 對象
*/
def apply(playerName: String, age: Int): PlayerInfo = new PlayerInfo(playerName, age, "Manchester City F.C.")
/**
* main 方法
* @param args
*/
def main(args: Array[String]): Unit = {
// 定義球員信息對象,有了 apply 方法后,不再需要 new 關(guān)鍵字
val player: PlayerInfo = PlayerInfo("Erling Haaland", 23)
println(player.hello())
// 執(zhí)行共生對象的 myDream 方法
// 可以訪問共生類的私有 playerName
println(this.myDream(player.playerName))
}
}
3.2.2 unapply 方法
unapply 方法通常用于模式匹配。它是 Extractor 模式的一部分,允許你從對象中提取部分信息,并將其與模式進(jìn)行匹配。
例如:
/**
* 球員信息類
*/
class PlayerInfo(private var playerName: String, var age: Int, var club: String) {
def hello(): String = {
s"Hey buddy, I am ${this.playerName} of ${this.club}, ${this.age} years old!"
}
}
/**
* PlayerInfo 類的共生對象
*/
object PlayerInfo {
/**
* 定義 apply 方法,新建一個 PlayerInfo 對象
*
* @param playerName 球員名稱
* @param age 年齡
* @return {@link PlayerInfo} 對象
*/
def apply(playerName: String, age: Int): PlayerInfo = new PlayerInfo(playerName, age, "Manchester City F.C.")
/**
* 定義 unapply,作為提取器,提取球員 姓名,年齡,俱樂部
* @param playerInfo 球員信息對象
* @return
*/
def unapply(playerInfo: PlayerInfo): Option[(String, Int, String)] = Some(playerInfo.playerName, playerInfo.age, playerInfo.club)
/**
* main 方法
* @param args
*/
def main(args: Array[String]): Unit = {
// 定義球員信息對象,有了 apply 方法后,不再需要 new 關(guān)鍵字
val player: PlayerInfo = PlayerInfo("Erling Haaland", 23)
player match {
case PlayerInfo(name, age, club) => println(s"name: ${name}, age: ${age}, club: ${club}")
case _ => println("Not matched")
}
}
}
在上面的代碼中,unapply 方法從 PlayerInfo 對象中提取了名字、年齡和俱樂部,并將它們作為元組返回。在 match 表達(dá)式中,case PlayerInfo(name, age, club) 部分使用了模式匹配,它調(diào)用了 PlayerInfo 伴生對象的 unapply 方法來提取 PlayerInfo 對象的信息,并與模式中的名字、年齡和俱樂部進(jìn)行匹配。
柚子快報(bào)激活碼778899分享:8 scala的伴生對象
參考文章
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場。
轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。