第04章 类和对象
1 类、字段和方法
class ChecksumAccumulator {
//不加修饰符默认是public
private var sum = 0;
//b 是 val 类型
def add(b: Byte): Unit = sum += b;
//
def checksum(): Int = ~(sum & 0xFF) + 1
}
- public 是 scala默认的访问级别
- scala方法参数都是val类型
- 没有任何显式的return语句时,scala方法返回的是该方法计算出的最后一个(表达式的)值
- 副作用通常来说是改变方法外部的某种状态或者执行I/O的动作
2 分号推断
scala 中,每条语句的最后的分号通常是可选的,如果一行包含多条语句,那么分号就必要的
x
+ y
//scala 会将上面代码解析成2条语句 x; +y
//如果希望解析成单挑语句 x + y,可以把语句包括在括号里
(x +
y)
3 单例对象
scala 不允许有静态成员,对此场景scala提供了单例对象(singleton object)
当单例对象跟某个类公用一个名字时,它被称作这个类的伴生对象,必须在同一个源码文件中定义类和伴生对象
class ChecksumAccumulator {
private var sum = 0;
def add(b: Byte): Unit = sum += b;
def checksum(): Int = ~(sum & 0xFF) + 1
}
import scala.collection.mutable
object ChecksumAccumulator {
private val cache = mutable.Map.empty[String, Int]
def calculate(s: String): Int = {
if (cache.contains(s)) {
//cache.get(s) 返回Option
//cache.get(s).get
cache(s)
} else {
val acc = new ChecksumAccumulator
for (c <- s) {
acc.add(c.toByte)
}
var cs = acc.checksum()
cache += (s -> cs)
cs
}
}
}
类和它的单例对象可以相互访问对方的私有成员
定义单例对象不会定义类型,类和单例对象的一个区别是单例对象不接受参数,而类可以
4 scala应用程序
import ChecksumAccumulator.calculate
object Summer {
def main(args: Array[String]): Unit = {
for (arg <- args) {
println(arg + ":" + calculate(arg))
}
}
}
- import ChecksumAccumulator.calculate 这个引入可以在后续代码中使用这个方法的简单名称
- scala源文件都隐式的引入了java.lang和scala包的成员,以及名为Predef的单例对象的所有成员,当你在scala源码中调用println时,实际上是调用了Predef的println方法。当你写assert时,实际上是调用了Predef.assert
5 App特质
import ChecksumAccumulator.calculate
object FallWinterSpringSummer extends App {
for (season <- List("fall", "winter", "spring")) {
println(season + ":" + calculate(season))
}
}
继承App时,代码直接写在单例对象的花括号里,通过名为args参数来访问命令行参数