Scala 類和對象 (二)

2018-09-28 18:15 更新

類和對象 (二)

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

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
       }
}

這個對象和上一篇創(chuàng)建的類 ChecksumAccumulator 同名,這在 Scala 中把這個對象成為其同名的類的“伴侶”對象( Companion object )。 如果你需要定義的類的 companion 對象,Scala 要求你把這兩個定義放在同一個文件中。類和其 companion 對象可以互相訪問對方的私有成員。

如果你是 Java 成員,可以把 Singleton 對象看成以前 Java 定義靜態(tài)成員的地方。你可以使用類似 Java 靜態(tài)方法的方式調用 Singleton 對象的方法,比如下面為這個例子完整的代碼:

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 對象不僅限于作為靜態(tài)對象的容器,它在 Scala 中也是頭等公民,但僅僅定義 Singleton 對象本身不會創(chuàng)建一個新的類型,你不可以使用 new 再創(chuàng)建一個新的 Singleton 對象(這也是 Singleton 名字的由來),此外和類定義不同的是,singleton 對象不可以帶參數(類定義參數將在后面文章介紹)。

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

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

這是一個最簡單的 Scala 程序,HelloWorld 是一個 Singleton 對象,它包含一個 main 方法(可以支持命令行參數),和 Java 類似,Scala 中任何 Singleto 對象,如果包含 main 方法,都可以作為應用的入口點。

在這里要說明一點的是,在 Scala 中不要求 public 類定義和其文件名同名,不過使用和 public 類和文件同名還是有它的優(yōu)點的,你可以根據個人喜好決定是否遵循 Java 文件命名風格。

最后提一下 Scala 的 trait 功能,Scala 的 trait 和 Java 的 Interface 相比,可以有方法的實現(這點有點像抽象類,但如果是抽象類,就不會允許繼承多個抽象類)。Scala 的 Trait 支持類和 Singleton 對象和多個 Trait 混合(使用來自這些 Trait 中的方法,而不時不違反單一繼承的原則)。

Scala 為 Singleton 對象的 main 定義了一個 App trait 類型,因此上面的例子可以簡化為:

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

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

scalac Helloworld.scala

編譯好之后,運行該應用

scala HelloWord

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

以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號