scala语言中是没有static关键字的,也就是说不能将类的方法或者字段声明为static,那如何实现相同的功能呢。scala提供了object关键字来实现同样的功能。
java中static关键字表明类只有这一个对象(即单例对象),scala是通过object关键字来定义,我们定义如下;
object Accounts { private var curAmountNum = 0 def getUniqNum() = { curAmountNum += 1 curAmountNum } }一些注意说明如下: 1. 构造时机: object关键字定义的“对象”并不会在一开始被构造,而是在第一次使用时被构造,比如调用了Accounts.getUnuqNum()时候。 2. object和类拥有很多同样的特性,例外的是:不能提供构造器参数。
object对象常见使用场景:
存放一些工具函数或者常量共享不可变实例单例模式的一种实现在java中,我们大部分需要的是静态对象和非静态对象结合的类,在scala中,是通过object定义和class类同名的object对象“伴生”达到同样目的。
class Accounts(var balance : Double = 0.0) { val id = Accounts.getUniqNum() def addBalance(amount : Double) : Unit = {balance += amount} } // Accounts类的伴生对象 object Accounts { private var curAmountNum = 0 def getUniqNum() = { curAmountNum += 1 curAmountNum } } object Main { def main(args: Array[String]) { val myAccount = new Accounts(10.0) myAccount.addBalance(20.3) print("account1 - id:" + myAccount.id + " amount:" + myAccount.balance + "\n") val myAccount2 = new Accounts(10.0) print("account2 - id:" + myAccount2.id + " amount:" + myAccount2.balance) } }运行输出如下:
account1 - id:1 amount:30.3 account2 - id:2 amount:10.0注意事项: 类和它的伴生对象可以相互访问私有成员,它们必须定义在同一个源文件中。
object对象可以扩展类以及一个或者多个特质,结果是扩展了指定类或者特质的类的对象(new出来的对象,不是object对象),并拥有对象定义中给出的所有特性。 比如一个场景:可共享使用的缺省默认处理object对象,比如程序中一个可撤销动作的类:
abstract class UndoableAction(val description : String) { def undo() : Unit def redo() : Unit } // 缺省行为,什么都不做 object DoNothingAction extends UndoableAction("don nothing") { override def undo() { } override def redo() { } }上面的DoNothingAction的object对象就可以用于任何缺省的地方。
scala程序启动应用有两种方法,其一让类继承App,其二是定义一个对象并定义main方法,要通过main方法直接启动程序,就需要定义一个object对象并在其中定义main函数,具体示例可以上面“伴生对象”中的main函数入口。 当继承App时候,继承体会执行,示例如下:
object Main extends App { print("start begin\n") DoNothingAction.redo() DoNothingAction.undo() def testFunc(): Unit = { println("test func") } } abstract class UndoableAction(val description : String) { def undo() : Unit def redo() : Unit } // 缺省行为,什么都不做 object DoNothingAction extends UndoableAction("don nothing") { override def undo() { print("undo nothing") } override def redo() { print("redo nothing") } }输出为:
start begin redo nothing undo nothingscala语言的追求一大特性就是简介,考虑一下如下数组的创建:
val a = new Array(new Person("John"), new Person("Paul"))其中有很多的new,如果是如下方式是不是更好呢?
val a = Array(Person("John"), Person("Paul"))这在scala语言中就是通过apply方法实现的,而apply方法是定义在类的伴生对象中,方法名是apply,参数和返回值和构造函数相同,比如Person类的定义如下:
class Person (val name : String) { } object Person { def apply(name : String) : Person = { new Person(name) } }