Scala開發教程(5): 類和對象 (二)

前面提到Scala比Java更加面向對象,這是因爲Scala不允許類保護靜態元素(靜態變量或靜態方法)。在Scala中提供類似功能的是成爲“Singleton(單例對象)“的對象。在Scala中定義Singleton對象的方法除了使用object,而非class關鍵字外和類定義非常類似,下面例子創建一個ChecksumAccumulator對象:

1 object ChecksumAccumulator {
2    private val cache = Map [String, Int] ()
3    def calculate(s:String) : Int =
4       if(cache.contains(s))
5          cache(s)
6       else {
7          val acc=new ChecksumAccumulator
8          for( c <- s)
9             acc.add(c.toByte)
10          val cs=acc.checksum()
11          cache += ( s -> cs)
12          cs
13        }
14 }

這個對象和上一篇創建的類ChecksumAccumulator同名,這在Scala中把這個對象成爲其同名的類的“伴侶”對象(Companion object)。 如果你需要定義的類的companion對象,Scala要求你把這兩個定義放在同一個文件中。類和其companion對象可以互相訪問對方的私有成員。
如果你是Java成員,可以把Singleton對象看成以前Java定義靜態成員的地方。你可以使用類似Java靜態方法的方式調用Singleton對象的方法,比如下面爲這個例子完整的代碼:

1 import scala.collection.mutable.Map
2 class ChecksumAccumulator{
3    private var sum=0
4    def add(b:Byte) :Unit = sum +=b
5    def checksum() : Int = ~ (sum & 0xFF) +1
6 }
7  
8 object ChecksumAccumulator {
9    private val cache = Map [String, Int] ()
10    def calculate(s:String) : Int =
11       if(cache.contains(s))
12          cache(s)
13       else {
14          val acc=new ChecksumAccumulator
15          for( c <- s)
16             acc.add(c.toByte)
17          val cs=acc.checksum()
18          cache += ( s -> cs)
19          cs
20        }
21 }
22  
23 println ( ChecksumAccumulator.calculate("Welcome to Scala Chinese community"))

Scala 的singleton對象不僅限於作爲靜態對象的容器,它在Scala中也是頭等公民,但僅僅定義Singleton對象本身不會創建一個新的類型,你不可以使用new再創建一個新的Singleton對象(這也是Singleton名字的由來),此外和類定義不同的是,singleton對象不可以帶參數(類定義參數將在後面文章介紹)。

回過頭來看看我們的第一個例子”Hello World“。

1 object HelloWorld {
2   def main(args: Array[String]) {
3     println("Hello, world!")
4   }
5 }

這是一個最簡單的Scala程序,HelloWorld 是一個Singleton對象,它包含一個main方法(可以支持命令行參數),和Java類似,Scala中任何Singleto對象,如果包含main方法,都可以作爲應用的入口點。
在這裏要說明一點的是,在Scala中不要求public類定義和其文件名同名,不過使用和public類和文件同名還是有它的優點的,你可以根據個人喜好決定是否遵循Java文件命名風格。
最後提一下Scala的trait功能,Scala的trait 和Java 的Interface相比,可以有方法的實現(這點有點像抽象類,但如果是抽象類,就不會允許繼承多個抽象類)。Scala的Trait支持類和Singleton對象和多個Trait混合(使用來自這些Trait中的方法,而不時不違反單一繼承的原則)。
Scala爲Singleton對象的main定義了一個App trait類型,因此上面的例子可以簡化爲:

1 object HelloWorld extends App{
2    println("Hello, world!")
3 }

這段代碼就不能作爲腳本運行,Scala的腳本要求代碼最後以表達式結束。因此運行這段代碼,需要先編譯這段代碼:
scalac Helloworld.scala

編譯好之後,運行該應用

scala HelloWord

注意: Scala提供了一個快速編譯代碼的輔助命令fsc (fast scala compliler) ,使用這個命令,只在第一次使用fsc時啓動JVM,之後fsc在後臺運行,這樣就避免每次使用scalac時都要載入相關庫文件,從而提高編譯速度。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章