物件:Object
1.單例物件
2.伴生物件
3.擴充套件類或特質的物件
4.apply方法
5.應用程式物件
6.列舉
1.單例物件
Scala中沒有你靜態方法或靜態欄位,可以用object這個語法結構來實現這個目的。物件定義某個類的單個例項,包含了你想要的特性
object ObjectOps { private var lastNumber = 0 def newUniqueNumber() = {lastNumber+=1;lastNumber} /* *物件的構造器在該物件第一次被使用時呼叫,在本例中,ObjectOps的構造器在Object.newUniqueNumber()的首次呼叫時執行 * 如果一個物件從未被使用,那麼他的構造器也從未被呼叫 * 物件本質上會擁有類的所有特性,只有一個例外——不能提供構造器引數 * 對於在Java中使用單例物件的地方,在Scala中都可以用物件來實現 * 1.作為存放工具函式或常量的地方 * 2.高效的共享單個不可以變例項 * 3.需要單個例項來協調某個服務時 */ }
2.伴生物件
在Java中你會用到既有例項方法又有靜態方法的類
在Scala中你可以通過類與類同名的伴生物件來實現
1 class Accounts { 2 //l類和它的伴生物件可以互相訪問私有屬性,但是必須在同一個原始檔中 3 val id = Accounts.newUniqueNumber() 4 private var balance = 0.0 5 def deposit(amount : Double){balance += amount} 6 } 7 /* 8 *說明:類的伴生物件可以被訪問,但並不在作用域中,如上,Accounts類必須通過Accounts.newUniqueNumber()而不是直接 9 * newUniqueNumber()來呼叫伴生物件的方法 10 */ 11 object Accounts{ //伴生物件 12 private var lastNumber = 0 13 private def newUniqueNumber() = {lastNumber+=1;lastNumber} 14 }
3.擴充套件類或特質的物件
一個object可以擴充套件類以及一個或多個特質,其結果是一個擴充套件了指定類以及特質的類的物件,同時擁有在物件定義中給出的所有特性
1 //一個有用的使用場景是給出可被共享的預設物件eg:在程式中引入一個可撤銷動作的類 2 abstract class UndoableAction(val desctiption : String ) { 3 def undo() : Unit 4 def redo() : Unit 5 } 6 7 object DoNotingAction extends UndoableAction("Do Thing"){ 8 override def undo(): Unit = {} 9 10 override def redo(): Unit = {} 11 //DoNotingAction物件可以被所有需要這個預設行為的地方公用 12 val actions = Map("open" -> DoNotingAction,"save" -> DoNotingAction) 13 }
4.apply方法
Object(引數列表),此時apply方法會被呼叫
這樣返回的是半生類的物件
Array物件定義了apply方法,我們可以這樣來建立陣列
Array("John","had","Alice")
為什麼不用構造器呢?對於巢狀表示式而言,省去new會方便很多
Array(Array(1,2),Array("a","b"))
1 class Account private (val id : Int ,initialBalance : Double){ 2 private var balance = initialBalance 3 } 4 5 object Account{ 6 private var lastNumber = 0 7 private def newUniqueNumber() = {lastNumber+=1;lastNumber} 8 def apply(initialBalance : Double): Unit ={ 9 new Account( newUniqueNumber(),initialBalance ) 10 } 11 //這樣一來就可以如下這種方式來構造賬號了: 12 13 14 def main(args: Array[String]): Unit = { 15 val acct = Account(1000.0) 16 17 } 18 }
5.應用程式物件
每個Scala程式都必須從一個物件的main方法開始。,這個方法的型別為Array[String]=>Unit:
1 object Hello1 { 2 def main(args: Array[String]): Unit = { 3 println("Hello world") 4 } 5 } 6 // 除了每次都提供main方法外,你也可以擴充套件APP特質,然後將程式程式碼放入構造器方法體內 7 object Hello2 extends App{ 8 println("Hello world") 9 //如果怒需要命令列引數,則可以通過args屬性得到: 10 if(args.length > 0){ 11 println("hello" + args(0)) 12 }else{ 13 println("Hello world") 14 } 15 }
6.列舉
和Java不一樣,Scala中沒有列舉型別,不過標準類庫提供了一個Enumeration助手類,用於產出列舉
定義一個擴充套件Enumeration類的物件,並以Value方法呼叫初始化列舉中的所有可選值
object EnumOps extends Enumeration{ //val Red,Yellow,Blue = Value /* *在這裡我們定義了三個欄位Red,Yellow,Blue,然後用value呼叫將他們初始化,這是如下程式碼的簡寫 * val Red = Value * val Yellow = value * val Blue = value * 每次呼叫都會返回內部類的新例項,該內部類叫Value * 或者你也可以向Value傳入ID,名稱,或者兩個都傳 */ val Red = Value(0,"Stop") val Yellow = Value(10) val Blue = Value("GO") //如果不指定,則ID將前一個列舉值基礎上加1,從零開始,預設名稱為欄位名 //定義完成後就可以通過EnumOps.Red來引用列舉值了 //也可以通過 import EnumOps._ } object LightColor extends Enumeration{ type LightColor = Value val Red,Yellow,Blue = Value import LightColor._ def doWhat(color : LightColor): Unit ={ if(color == Red) "Stop" else if(color == Yellow) "hurry up" else "Go" } //列舉值的ID可以通過ID方法返回,名稱通過toString返回 def main(args: Array[String]): Unit = { for(c <-LightColor.values) println(c.id +":"+ c) //最後,你可以通過列舉值或名稱來查詢定位 LightColor(0) LightColor.withName("Red") } }