Scala伴生类和伴生对象
单例对象与类同名时,这个单例对象被称为这个类的伴生对象,而这个类被称为这个单例对象的伴生类。伴生类和伴生对象要在同一个源文件中定义,伴生对象和伴生类可以互相访问其私有成员。不与伴生类同名的单例对象称为孤立对象。
看看例子:
import scala.collection.mutable.Map
class ChecksumAccumulator {
private var sum = 0
def add(b: Byte) {
sum += b
}
def checksum(): Int = ~(sum & 0xFF) + 1
}
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)
println("s:"+s+" cs:"+cs)
cs
}
def main(args: Array[String]) {
println("Java 1:"+calculate("Java"))
println("Java 2:"+calculate("Java"))
println("Scala :"+calculate("Scala"))
}
}
ChecksumAccumulator单例对象有一个方法,calculate,用来计算所带的String参数中字符的校验和。它还有一个私有字段,cache,一个缓存之前计算过的校验和的可变映射。2方法的第一行,“if (cache.contains(s))”,检查缓存,看看是否传递进来的字串已经作为键存在于映射当中。如果是,就仅仅返回映射的值,“cache(s)”。否则,执行else子句,计算校验和。else子句的第一行定义了一个叫acc的val并用新建的ChecksumAccumulator实例初始化它。下一行是个for表达式,对传入字串的每个字符循环一次,并在其上调用toByte把字符转换成Byte,然后传递给acc所指的ChecksumAccumulator实例的add方法。完成了for表达式后,下一行的方法在acc上调用checksum,获得传入字串的校验和,并存入叫做cs的val。下一行,“cache += (s -> cs)”,传入的字串键映射到整数的校验和值,并把这个键-值对加入cache映射。方法的最后一个表达式,“cs”,保证了校验和为此方法的结果。
这里打印的结果是:
s:Java cs:-130
Java 1:-130
Java 2:-130
s:Scala cs:-228
Scala :-228
问题来了,ChecksumAccumulator单例对象是不能new的,但是在代码中出现了val acc = new ChecksumAccumulator,这不是矛盾吗?其实不然,这里new的其实是ChecksumAccumulator单例对象的伴生类,即ChecksumAccumulator类,而伴生类和伴生对象可以互相访问对方的私有成员,所以acc可以访问ChecksumAccumulator单例对象的cache变量。同理,那么第一次测试“Java”字符串的时候,acc实例执行了checksum()方法,接下来并把这个数据存到cache这个val中。在第二次测试“Java”字符串的时候,程序是直接从cache变量中获取到了数据,并返回。
这里也可以看出类和单例对象的一个差别是,单例对象是在第一次访问的时候初始化,不可以new,不能带参数,而类可以new,可以带参数。每个单例对象都被作为由一个静态变量指向的虚构类:synthetic class的一个实例来实现,因此它们与Java静态类有着相同的初始化语法。
参考:《Scala编程》
Scala伴生类和伴生对象的更多相关文章
- Scala入门1(单例对象和伴生类)
一.Hello World程序的执行原理 参考http://blog.csdn.net/zhangjg_blog/article/details/22760957 object HelloWorld{ ...
- Scala学习笔记之伴生对象
所谓伴生对象, 也是一个Scala中的单例对象, 使用object关键字修饰. 除此之外, 还有一个使用class关键字定义的同名类, 这个类和单例对象存在于同一个文件中, 这个类就叫做这个单例对象的 ...
- scala学习-类与对象
类 / 对象 [<快学Scala>笔记] 一.类 1.Scala中的类是公有可见性的,且多个类可以包含在同一个源文件中: class Counter{ private var value ...
- 【scala】类的定义和单例对象
一.类的定义 Scala类的定义跟JAVA中类的定义基本是一样的. 示例 class ChecksumAccumulator{ var sum = 0;//Scala默认关键字为public priv ...
- Scala编程入门---面向对象编程之对象
对象 Object,相当于class单个实例,通常在里面放一些静态的filed或method 第一次调用object方法时候,就会执行object的constructor,也就是Object中不在me ...
- Scala基础:面向对象之对象和继承
对象 object 相当于 class 的单个实例,通常在里面放一些静态的 field 或者 method:在 Scala 中没有静态方法和静态字段,但是可以使用 object 这个语法结构来达到同样 ...
- scala 伴生对象与伴生类
package cn.scala_base.oop.scalaobject import java.security.cert.Extension /** * object的构造器必须是无参的,且且构 ...
- scala学习手记15 - 独立对象和伴生对象
上一节中的单例对象MarkerFactory 就是一个独立对象的例子.尽管它管理着Marker类,但是它并没有关联到任何类上. scala也可以创建关联到类上的对象.这样的对象同类共享同一个名字,这样 ...
- 快学Scala 第九课 (伴生对象和枚举)
Scala没有静态方法和静态字段, 你可以用object这个语法结构来达到同样的目的. 对象的构造器只有在第一次被使用时才调用. 伴生对象apply方法: 类和它的伴生对象可以互相访问私有特性,他们必 ...
随机推荐
- Counting Sequences_线段树***
Description For a set of sequences of integers{a1,a2,a3,...an}, we define a sequence{ai1,ai2,ai3...a ...
- Unity3D DllNotFoundException/System.DllNotFoundException
Unity System.DllNotFoundException Unity Fallback handler could not load library D:/91yGame/SparrowCD ...
- php-数据库访问--增、删、改
建立一个登录页面 <form action="chuli.php" method="post"> <div>用户名:<input ...
- CCSprite setTextureRect 的坐标的坑
setTextureRect显示区域所使用的坐标系是跟cocos2d-x的系统坐标系是有区别的,这个坐标系使用的一般屏幕坐标系,也就是以左上角为原点(0,0). Sprite的AnchorPoint对 ...
- Linux学习方法
应该如何提问? 先要尝试自己解决 - 帮助 - 文档 - 示例 提问的智慧 - 问题详尽 - 贴图
- 获取 .net framework 路径
要获取当前程序所使用的.netframework路径: System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory(); ...
- ABBYY有哪些图像处理选项
ABBYY PDF Transformer+ 这款Ocr图文识别软件提供多种图像处理选项,可提高源图像的质量,便于准确地识别光学字符.我们扫描纸质文档或从图像文件创建 PDF 时,务必选择合适的图像处 ...
- mac10.9下eclipse的storm开发环境搭建
--------------------------------------- 博文作者:迦壹 博客地址:http://idoall.org/home.php?mod=space&uid=1& ...
- webpack-dev-server、webpack-dev-middleware、webpack-hot-middleware区别
webpack-dev-server: 它是一个静态资源服务器,只用于开发环境: webpack-dev-server会把编译后的静态文件全部保存在内存里: webpack-dev-middlewar ...
- Document types require more than xhtml1.0
这个东西只会在比较低版本的浏览器中会出现,比如IE7及以下会出这个错误. 错误的根源是html页面没有考虑浏览器兼容性问题. 在页面头部加入下面的内容即可解决标题中的问题 <!DOCTYPE h ...