Scala语音备忘拾遗_5 – 对象(Object) 伴生对象 伴生类
Jul062020
Scala语音备忘拾遗_5 – 对象(Object) 伴生对象 伴生类
Scala没有静态方法或字段,对象(Object)语法可以用来实现Java中的静态类/方法/字段.同时对象提供了更多特性.
1. 作为单例对象
- 对象(Object)定义了某个类的单例实例,调用对象的方法时,使用对象名直接调用.
- 对象也有构造器,在该对象第一次被使用时调用.
- 对象本质上可以拥有类的所有特性,只有一个例外:
你不能提供构对象造器参数
. - 对象通常时作为存放工具函数或常量的地方,可高效地共享单个不可变实例。
package com.jack.yin
object TestAccount {
val TEST_CONSTANT = "TEST_CONSTANT"
private var lastNumber = 0
def newUniqueNumber() = {lastNumber += 1; lastNumber}
}
object TestObject extends App {
println(TestAccount.newUniqueNumber()) // 1
println(TestAccount.newUniqueNumber()) // 2
println(TestAccount.TEST_CONSTANT) // 存放常量
}
2. 作为伴生对象
- 同一源文件中定义的同名的class和object,class是object的伴生类,object是class的伴生对象.
- 类和它的伴生对象可以相互访问私有特性,它们必须存在于同一个源文件中.
- 伴生类中调用伴生对象方法需要使用伴生对象名作为前缀调用.
class Account(var name:String,var balance:Int) {
private val privateFieldInClass = "privateFieldInClass"
def printInfo(): Unit ={
println(s"${name} 's balance is ${balance}")
}
def invokeFunFromObject():Unit = {
// 伴生类中调用伴生对象方法需要使用伴生对象名作为前缀调用
Account.printInfoInObj()
}
override def toString = s"Account($name, $balance)"
}
object Account {
def apply(name:String,num:Int) = {
new Account(name,num)
}
// object方法,相当于定义一个静态方法
def staticFunc():Unit = {
println("staticFunc")
}
def printInfoInObj(): Unit = {
// 直接 new 出对象
val account = new Account("aaa",2)
println(account)
// 可以访问class 中的private 字段,但是 object 必须和 class定义在同一个文件中
println(s"${account.privateFieldInClass} ")
}
def printInfoInObj_2(): Unit = {
// 调用 apply方法
val account = Account("aaa",2)
println(account)
// 可以访问class 中的private 字段,但是 object 必须和 class定义在同一个文件中
println(s"${account.privateFieldInClass} ")
}
}
3. apply方法简化构造类的实例
如下所示, 伴生对象定义了方法apply(),方法接受参数,返回Account实例,可以使用 var account = Account("Jack",24) 来构造一个account实例.
这里省略了new
,因为正常情况下,使用构造函数生成一个实例的调用方式为 var account = new
Account("Jack",24)
def apply(name:String,num:Int) = {
new Account(name,num)
}
4. 对象可以扩展类或特质
abstract class UndoableAction(val desc:String) {
def undo():Unit
def redo():Unit
}
// 这里继承UndoableAction 时指定了构造参数,看起来像继承了一个`抽象类的实例`
object DoNothingAction extends UndoableAction("Do Nothing") {
override def undo(): Unit = {}
override def redo(): Unit = {}
}
5. 应用程序对象
通常,一个scala程序的起点是一个object中的main方法. 也可以用一个object继承App特质,然后将代码放入构造器方法内.
如果需要命令行参数,可以通过args属性得到.
注: 定义一个类/对象的大括号内的所有语句都属于构造器方法的方法体.
object Hello extends App {
if(args.length > 0) {
println(f"Hello ${args[0]}")
} else {
println("Hello World!")
}
}
赞 赏 微信赞赏
支付宝赞赏