单例对象与类同名时,这个单例对象被称为这个类的伴生对象,而这个类被称为这个单例对象的伴生类。伴生类和伴生对象要在同一个源文件中定义,伴生对象和伴生类可以互相访问其私有成员。不与伴生类同名的单例对象称为孤立对象。(弥补了Scala中缺少static关键字的缺陷,可以与java无缝对接)

import scala.collection.mutable.Mapclass ChecksumAccumulator {private var sum = 0def 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 ChecksumAccumulatorfor (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-spark]5. 伴生类和伴生对象相关推荐

  1. 每天学一点Scala之 伴生类和伴生对象

    1.  object 相当于class的单个实例,因此,在object里声明的变量都是静态变量,静态方法 2.  在object里声明的变量,都是全局变量,也就是类的公共属性,或者类似于java中父类 ...

  2. 大数据开发语言Scala(三)——伴生类和伴生对象

    Scala语言是完全面向对象的语言,所以并没有静态的操作(即在Scala中没有静态的概念).但是为了能够和Java语言交互(因为Java中有静态概念),就产生了一种特殊的对象来模拟类对象,该对象为单例 ...

  3. Scala中Object和Class区别(伴生类和伴生对象)

    文章目录 一,介绍 二,类Class 2.1 类定义 2.2 构造器 1.基本语法 2.构造器参数 2.3 私有成员和Getter/Setter语法 三,单例对象Object 四,伴生对象和伴生类介绍 ...

  4. Scala伴生类和伴生对象

    单例对象与类同名时,这个单例对象被称为这个类的伴生对象,而这个类被称为这个单例对象的伴生类.伴生类和伴生对象要在同一个源文件中定义,伴生对象和伴生类可以互相访问其私有成员.不与伴生类同名的单例对象称为 ...

  5. 样例类,样例对象,伴生类,伴生对象

    样例类 使用case class 类名 定义 case class Person(var name:String, var age:Int) 可以直接使用 : Person("张三" ...

  6. [Scala基础]-- 伴生类和伴生对象

    Scala比 Java 更面向对象的一个方面是 Scala 没有静态成员.替代品是,Scala 有: 单例对象:singleton object. 除了用 object 关键字替换了 class 关键 ...

  7. scala的伴生类和伴生对象所属类是什么?

    文章目录 说在前面 运行原理 代码体现 解析 说在前面 scala是纯面向对象的语言,C是纯面向过程的语言,Java就是面向过程+面向对象的语言. 在说到伴生对象之前,要先说到java的static关 ...

  8. scala案例_Scala案例类和案例对象深入(第1部分)

    scala案例 发表简短目录 (Post Brief TOC) Introduction介绍 What is Case Class什么是案例类 What is Case Object什么是案例对象 S ...

  9. scala案例_Scala案例类和案例对象深入(第2部分)

    scala案例 发表简短目录 (Post Brief TOC) Introduction介绍 Scala's Case Class Benefit-6Scala案例类权益6 Advantages of ...

最新文章

  1. [51单片机学习笔记ONE]-----LED灯的多种使用方法
  2. 你知道 URL 后面的这些 utm_xxx 参数都是干嘛的吗?
  3. 人民日报新媒体中心接入神策数据,媒体阅读体验新升级
  4. 帮助别人是一种快乐!
  5. SpringMVC:400 Bad Request
  6. 动画专题:属性动画:插值器AccelerateDecelerateInterpolator 加速插值器
  7. 打开cmd 的方式和常用的cmd快捷键
  8. 企业工资管理系统论文
  9. 实现折叠工具栏CollapsingToolbarLayout(折叠工具栏布局)
  10. ecs 导出mysql文件_mysql导出数据库文件
  11. 计算机exo乐谱,History钢琴简谱-数字双手-EXO
  12. HDU 6438 Buy and Resell【贪心】
  13. Speedoffice(word)如何插入文字水印
  14. 郑州财经学院第54次全国计算机,郑州财经学院第二期教师博士班开班
  15. 3dsmax顶点死活焊接不上的原因!
  16. 许昌学院计算机学院张伶俐,【优秀毕业生故事系列】之四:厉害了,我的班!...
  17. GD32F303的PWM实现LED呼吸灯的方法
  18. 量化交易:如何让回测更贴近实盘结果
  19. 仿六间房 新浪秀场网页视频聊天室 网页视频直播系统
  20. 电力系统静/暂态稳定性Matlab编程/ Simulink仿真

热门文章

  1. android 之ViewStub
  2. http/https面试总结
  3. ops中set_sysclk set_clkdiv set_pll详解
  4. SKIP-NAME-RESOLVE ——错误的使用时机造成用户权限
  5. [实战演练]腾讯2013年校招软件开发类笔试题目(选择题部分)
  6. hdu 5139(离线处理)
  7. NYOJ 303 序号转换 数学题
  8. php组合设计模式(composite pattern)
  9. python 面向对象(类)--学习笔记
  10. 1001.害死人不偿命的(3n+1)猜想