W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
前面提到 Scala 比 Java 更加面向?qū)ο螅@是因?yàn)?Scala 不允許類(lèi)保護(hù)靜態(tài)元素(靜態(tài)變量或靜態(tài)方法)。在 Scala 中提供類(lèi)似功能的是成為“Singleton(單例對(duì)象)”的對(duì)象。在 Scala 中定義 Singleton 對(duì)象的方法除了使用 object,而非 class 關(guān)鍵字外和類(lèi)定義非常類(lèi)似,下面例子創(chuàng)建一個(gè) ChecksumAccumulator 對(duì)象:
object ChecksumAccumulator {
private val cache = Map [String, Int] ()
def calculate(s:String) : Int =
if(cache.contains(s))
cache(s)
else {
val acc=new ChecksumAccumulator
for( c <- s)
acc.add(c.toByte)
val cs=acc.checksum()
cache += ( s -> cs)
cs
}
}
這個(gè)對(duì)象和上一篇?jiǎng)?chuàng)建的類(lèi) ChecksumAccumulator 同名,這在 Scala 中把這個(gè)對(duì)象成為其同名的類(lèi)的“伴侶”對(duì)象( Companion object )。 如果你需要定義的類(lèi)的 companion 對(duì)象,Scala 要求你把這兩個(gè)定義放在同一個(gè)文件中。類(lèi)和其 companion 對(duì)象可以互相訪問(wèn)對(duì)方的私有成員。
如果你是 Java 成員,可以把 Singleton 對(duì)象看成以前 Java 定義靜態(tài)成員的地方。你可以使用類(lèi)似 Java 靜態(tài)方法的方式調(diào)用 Singleton 對(duì)象的方法,比如下面為這個(gè)例子完整的代碼:
import scala.collection.mutable.Map
class ChecksumAccumulator{
private var sum=0
def add(b:Byte) :Unit = sum +=b
def checksum() : Int = ~ (sum & 0xFF) +1
}
object ChecksumAccumulator {
private val cache = Map [String, Int] ()
def calculate(s:String) : Int =
if(cache.contains(s))
cache(s)
else {
val acc=new ChecksumAccumulator
for( c <- s)
acc.add(c.toByte)
val cs=acc.checksum()
cache += ( s -> cs)
cs
}
}
println ( ChecksumAccumulator.calculate("Welcome to Scala Chinese community"))
Scala 的 singleton 對(duì)象不僅限于作為靜態(tài)對(duì)象的容器,它在 Scala 中也是頭等公民,但僅僅定義 Singleton 對(duì)象本身不會(huì)創(chuàng)建一個(gè)新的類(lèi)型,你不可以使用 new 再創(chuàng)建一個(gè)新的 Singleton 對(duì)象(這也是 Singleton 名字的由來(lái)),此外和類(lèi)定義不同的是,singleton 對(duì)象不可以帶參數(shù)(類(lèi)定義參數(shù)將在后面文章介紹)。
回過(guò)頭來(lái)看看我們的第一個(gè)例子 “Hello World“。
object HelloWorld {
def main(args: Array[String]) {
println("Hello, world!")
}
}
這是一個(gè)最簡(jiǎn)單的 Scala 程序,HelloWorld 是一個(gè) Singleton 對(duì)象,它包含一個(gè) main 方法(可以支持命令行參數(shù)),和 Java 類(lèi)似,Scala 中任何 Singleto 對(duì)象,如果包含 main 方法,都可以作為應(yīng)用的入口點(diǎn)。
在這里要說(shuō)明一點(diǎn)的是,在 Scala 中不要求 public 類(lèi)定義和其文件名同名,不過(guò)使用和 public 類(lèi)和文件同名還是有它的優(yōu)點(diǎn)的,你可以根據(jù)個(gè)人喜好決定是否遵循 Java 文件命名風(fēng)格。
最后提一下 Scala 的 trait 功能,Scala 的 trait 和 Java 的 Interface 相比,可以有方法的實(shí)現(xiàn)(這點(diǎn)有點(diǎn)像抽象類(lèi),但如果是抽象類(lèi),就不會(huì)允許繼承多個(gè)抽象類(lèi))。Scala 的 Trait 支持類(lèi)和 Singleton 對(duì)象和多個(gè) Trait 混合(使用來(lái)自這些 Trait 中的方法,而不時(shí)不違反單一繼承的原則)。
Scala 為 Singleton 對(duì)象的 main 定義了一個(gè) App trait 類(lèi)型,因此上面的例子可以簡(jiǎn)化為:
object HelloWorld extends App{
println("Hello, world!")
}
這段代碼就不能作為腳本運(yùn)行,Scala 的腳本要求代碼最后以表達(dá)式結(jié)束。因此運(yùn)行這段代碼,需要先編譯這段代碼:
scalac Helloworld.scala
編譯好之后,運(yùn)行該應(yīng)用
scala HelloWord
注意
: Scala 提供了一個(gè)快速編譯代碼的輔助命令 fsc (fast scala compliler) ,使用這個(gè)命令,只在第一次使用 fsc時(shí)啟動(dòng) JVM,之后 fsc 在后臺(tái)運(yùn)行,這樣就避免每次使用 scalac 時(shí)都要載入相關(guān)庫(kù)文件,從而提高編譯速度。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: