在调用对象的方法的时候, 如果有父类, 则具体执行的哪个类型的方法, 取决于运行时变量当前的类型, 而非定义变量的类型

class ChecksumAccumulator{
   private var sum=0

	 // 默认 public , b 的类型为 val , 无法在函数中修改 b 的值
   def add(b:Byte) :Unit = sum +=b 
   def checksum() : Int = ~ (sum & 0xFF) +1
}

class 中无法包含 静态变量或静态方法

Singleton 单例对象

object ChecksumAccumulator {
   private val cache = Map [String, Int] ()

   def calculate(s:String) : Int =
      if(cache.contains(s))
         cache(s)
      else {
         val acc=new ChecksumAccumulator // 实例化 class
         for( c <- s)
            acc.add(c.toByte)
         val cs=acc.checksum()
         cache += ( s -> cs)
         cs
       }
}

这个对象和上一个创建的类 ChecksumAccumulator 同名,这在 Scala 中把这个对象称为其同名的类的“伴侣”对象(Companion object)。 如果你需要定义类的 companion 对象,Scala 要求你把这两个定义放在同一个文件中。 类和其 companion 对象可以互相访问对方的私有成员

单独定义 object 无法使用 new 关键字实例化对象

调用

ChecksumAccumulator.calculate("Welcome to Scala Chinese community")

定义方法和操作符

对象支持重载, 所以定义了多个 + 方法的重载方法以支持不同的数据类型.

同样的也可以定义任何方法为操作符. 如下所示

val s = "Hello, World"
s indexOf 'o' // 用操作符的语法调用方法, 此时 indexOf 等同 中缀运算符
s toLowerCase // 后缀运算符

Scala 在实现前缀和后缀操作符的方法,其方法名都以 unary_- 开头