4.6 Scala中的static

Scala没有静态字段和静态方法。静态字段和静态方法会打破Scala所支持的完整的面向对象模型。不过,Scala也是完全支持类一级的属性和操作的。这就是伴生对象的作用。

回过头来看一下上面Marker的例子。如果能从Marker上得到各种原色固然是好事,但这个操作不应该在某个特定实例上执行,它应该是类一级的操作。换句话说,要是用Java的话,就会写成静态方法了。在Scala里,这个方法存在于伴生对象中:

ScalaForTheJavaEyes/Static.scala

  1. class Marker private (val color: String) {
  2. override def toString() : String = "marker color " + color
  3. }
  4. object Marker {
  5. private val markers = Map(
  6. "red" -> new Marker("red"),
  7. "blue" -> new Marker("blue"),
  8. "green" -> new Marker("green")
  9. )
  10. def primaryColors = "red, green, blue"
  11. def apply(color: String) = if (markers.contains(color))
  12. markers(color) else null
  13. }
  14. println("Primary colors are : " + Marker.primaryColors)
  15. println(Marker("blue"))
  16. println(Marker("red"))

输出如下:

  1. Primary colors are : red, green, blue
  2. marker color blue
  3. marker color red

我们在伴生对象里面写了primaryColors()方法(如果方法没有参数的话,方法定义中的括号是可以省略的)。在伴生对象Marker里调用这个方法的方式就跟调用Java类中的静态方法一样。

伴生对象还有另外一点好处:创建伴生类的实例不需要new关键字。这件妙事是apply()方法帮我们完成的,它是Scala提供的语法糖。上面的代码在调用Marker("blue")的时候,其实就是调用了Marker.apply("blue")。这是个轻量级的语法,让实例的创建或获取更加容易③。

③如果构造函数没有参数,就也不需要在new后面加括号——可以用new Sample格式取代new Sample()格式。

在本章里,我们学到了Scala对OO范式的支持。想必你已经准备好享受Scala的简洁和纯粹的面向对象特性了。下一章将讨论Scala的一个关键特性——静态类型。