对象: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 Enu