介绍
object
修饰符,单纯简单的理解 Scala中的object与Kotlin的object使用方式基本差不多。
单例对象
直接声明一个object的类,在kotlin与Scala中都是代表这个类是一个单例对象。
单例对象,自动进行实例化,使用时直接类名调用即可。
object HelloWord {
def hello(): Unit = {
println(s"Hello Scala! ${this}")
}
}
调用时:HelloWord.hello()
单例对象单独存在,即区别与下文中的伴生对象,则称为独立对象。
这种方式与Kotlin中的使用完全一样,由于Scala中没有static的存在,可以通过object来存放工具函数与常量等。
伴生对象
Companion Obejct
在Scala中object可以用来声明伴生对象,与之同时存在的是伴生类。即:伴生类与伴生对象是同时存在。
在同一个源文件中,同时声明一个同名的class与object,则class称为伴生类,object称为伴生对象。伴生类和伴生对象可以相互访问私有成员。
class Marker private(val color: String) {
println(s"Marker创建${this}")
override def toString: String = {
s"颜色标记:$color, ${super.toString}"
}
def visitCompanionObjectField(): Unit = {
println(Marker.markers)
}
}
object Marker {
private val markers: Map[String, Marker] = Map(
"red" -> new Marker("red"),
"blue" -> new Marker("blue"),
"green" -> new Marker("green")
)
def apply(color: String): Marker = {
println(s"apply, $color, ${this}")
if (markers.contains(color)) markers(color) else null
}
def getMarker(color: String): Marker = {
println(s"getMarker, $color, $this")
val marker = if (markers.contains(color)) markers(color) else null
if (marker != null) {
println(s"getMarkerColor:${marker.color}")
}
marker
}
}
如上伴生对象Marker可以访问 伴生类Marker 的私有属性 color
, 同样伴生类也可以访问伴生对象的私有属性 markers
。
注意:本质上伴生类与伴生对象不是同一个类,注意不要混淆。即伴生对象并不是伴生类的一个实例化。
通过将两个实例进行日志的输出,可以明显的做出区分:
//伴生对象输出
com.stone.scalademo.data.Marker$@369f73a2
//伴生类实例的输出
com.stone.scalademo.data.Marker@5f9d02cb
伴生对象当做工厂使用
上述的Marker示例中,在伴生对象Marker中有个函数 apply,通过这个方法我们可以让伴生对象作为一个伴生类的工厂来使用。
关于
apply
的这里不做具体讨论,后文再表。
即:通过如下调用可以直接获取一个伴生类的对象
val marker = Marker.apply("red")
为了能够更简洁的发挥作用,apply 方法的调用可以简写为
val marker = Marker("red")
如下的代码,通过单独的apply方法的使用,能够更好的说明工厂的使用。
object MarkerF {
def apply(color: String): MarkerF = new MarkerF(color)
}
class MarkerF private(val color: String) {
println(s"创建颜色:$color")
}
可以直接通过
MarkerF("color")
来生成新的伴生类MarkerF实例,省略了关键字 new