类和对象
你熟悉 Java,你会发现 Scala 里的概念相似,但不完全相同。所以即使你是一位 Java 大师,读一下本章也是有益的。
1.类字段和方法
class ChecksumAccumulator{
//class definition goes here
}
你可以创建类
ChecksumAccumulator对象:
new ChecksumAccumulator
类定义里,可以放置字段和方法,这些被统称为成员(member)。
要声明字段是私有的,可以把访问修饰符 private 放在字段的前面
class ChecksumAccumulator {
private var sum = 0
}
有了这个 ChecksumAccumulator 的定义,任何从类外部访问 sum 的尝试都会失败:
val acc = new ChecksumAccumulatoracc.sum = 5 //编译不过,因为sum是私有的
现在 sum 是私有的,所以唯一能访问 sum 的代码是定义在类自己里面的。除非我们定义什么方法,否则 ChecksumAccumulator 对任何人都没什么用处:
class ChecksumAccumulator { private var sum = 0
def add(b: Byte): Unit = {
sum += b }
def checksum(): Int = {
return ~(sum & 0xFF) + 1
}
}
传递给方法的任何参数都可以在方法内部使用。Scala里方法参数的一个重要特征是它们都是val,不是var。如果你想在方法里面给参数重新赋值,结果是编译失败:
def add(b: Byte): Unit = {
b += 1 // 编译不过,因为b是val sum += b
}
尽管在这个 ChecksumAccumulator 版本里的 add 和 checksum 方法正确地实现了预期的功能,你还是可以用更简洁的风格表达它们。
2.分号推断
Scala 程序里,语句末尾的分号通常是可选的。如果你愿意可以输入一个,但若一行里仅有一个语句也可不写。另一方面,如果一行里写多个语句那么分号是需要的:
val s = "hello";println(s)
如果你想输入一个跨越多行的语句,多数时候你只需输入,Scala 将在正确的位置分隔语句。例如,下面的代码被认为是一个跨四行的语句:
if (x < 2)
println("too small")
else
println("ok")
Scala 比 Java 更面向对象的一个方面是 Scala 没有静态成员。替代品是,Scala 有单例对象:singleton object。除了用 object 关键字替换了 class 关键字以外,
单例对象的定义看上去就像是类定义。
// 文件 ChecksumAccumulator.scala
import scala.collection.mutable.Map
object ChecksumAccumulator {
private val cache = Map[String, Int]()
def calculate(s: String): Int =
if (cache.contains(s))
cache(s)
else {
val acc = new ChecksumAccumulator
for (c <- s)
acc.add(c.toByte)
val cs = acc.checksum()
cache += (s -> cs)
cs
}
}
Scala提供了一种特质,scala.Application可以节省你一些手指的输入工作。
import ChecksumAccumulator.calculate
object FallWinterSpringSummer extends Application {
for (season <- List("fall","winter","spring"))
println(season + ": " + calculate(season))
}
使用这个特质的方法是,首先在你的单例对象名后面写上“extends Application” 。然后代之以 main 方法,你可以把想要放在 main 方法里的代码直接放在单例对象的大括号之间。就这么简单。之后可以像对其它程序那样编译和运行。