聊聊 Scala 的伴生对象及其意义
2019-04-22
关键字:Scala 伴生对象的作用
关于 Scala 伴生对象,比教材更详细的解释。
什么是伴生对象?
教材中关于伴生对象的解释是:实现类似 Java 中那种既有实例成员又有静态成员的类的功能。
为什么上面说它是一种 “功能” 呢?因为要想实现像 Java 中那样的类,光靠一个 Scala 类可不行。在 Scala 中,我们必须:
1. 定义一个 class 并在这里面实现所有的实例成员。
2. 添加一个 object ,这个 object 要与上面的 class 同名,然后在这里面实现所有的静态成员。
3. 定义的 class 与 object 必须在同一个文件内。
满足了上面 3 条要求以后,就可以实现类似 Java 中一个类既存在实例成员又存在静态成员的功能了。然后我们通常把第 2 步添加的 object 称为 “伴生对象” 。转化成代码,就像下面这样
class CompanionDemo {
println("new CompanionDemo clz")
def init(): Unit = {
// our codes...
}
}
object CompanionDemo {
println("new CompanionDemo object")
def prt(): Unit = {
// our codes...
}
}
伴生对象有什么特点?
毫无疑问,伴生对象这种存在最大的特点就是可以实现类似 Java 中那样,在同一个类里既有实例成员又有静态成员的功能。
另一个特点就是 class CompanionDemo 和 object CompanionDemo 虽然分开两处定义,但却可以访问对方的 private 变量及方法。访问私有属性的一个小示例如下
class CompanionDemo {
private var clzi = 0
def init(): Unit = {
println("variable in clz:" + clzi)
println("variable from object:" + CompanionDemo.obji)
CompanionDemo.access(this)
}
}
object CompanionDemo {
private var obji = 1
def access(clz: CompanionDemo): Unit = {
println("variable in object:" + obji)
println("variable from clz:" + clz.clzi)
}
}
相互访问私有属性
并通过如下代码来访问伴生对象
object cpDemp {
def main(args: Array[String]){
val cd = new CompanionDemo()
cd.init()
}
}
执行结果如下
variable in clz:0
variable from object:1
variable in object:1
variable from clz:0
如您所想的执行结果
伴生对象中要想访问对方的私有属性,需要注意以下 2 点
1. class 中要访问 object 中的私有属性,直接以 object 名来 “点” 相应的变量或方法即可,可以参考上面例子;
2. object 中要访问 class 中的私有属性,必须要通过 class 的对象引用来 “点” 相应变量或方法,可以参考上面例子。
伴生对象的意义是什么?
Scala 中没有 static 关键字,而 Scala 又运行与 JVM 之上,与 Java 类库完全兼容的编程语言,同时类中拥有静态属性又是如此的有必要,因此推出这个伴生对象机制就显得很有必要了。所以第 1 个意义就是为了弥补类中不能定义 static 属性的缺陷。
那我们知道,在 Java 中静态属性是属于类的,在整个 JVM 中只开辟一块内存空间,这种设定使得静态属性可以很节省内存资源,不用担心像实例属性那样有内存溢出的风险。在 Scala 中伴生对象本质上也是生成静态属性,所以这第 2 个意义就是节省内存资源。
既然静态属性在整个 JVM 中仅开辟一块内存空间,那就说明我们可以在所有实例当中共享这块内存里面的信息,所以第 3 个意义就是资源共享。
聊聊 Scala 的伴生对象及其意义的更多相关文章
- scala 类,伴生对象
1.属性的定义 编写一个PersonS类,并在其中定义一些属性,通过PersonS.scala 编译后的情况查看,可以知道不同修饰符修饰的属性分别会生成什么方法(set,get) package co ...
- scala伴生对象
package com.test.scala.test /** * 伴生对象指的是在类中建立一个object */ class AssociatedObject { private var count ...
- Scala学习教程笔记二之函数式编程、Object对象、伴生对象、继承、Trait、
1:Scala之函数式编程学习笔记: :Scala函数式编程学习: 1.1:Scala定义一个简单的类,包含field以及方法,创建类的对象,并且调用其方法: class User { private ...
- Scala单例对象、伴生对象实战详解
1.Scala单例对象 Scala单例对象是十分重要的,没有像在Java一样,有静态类.静态成员.静态方法,但是Scala提供了object对象,这个object对象类似于Java的静态类,它的成员. ...
- Scala学习笔记之伴生对象
所谓伴生对象, 也是一个Scala中的单例对象, 使用object关键字修饰. 除此之外, 还有一个使用class关键字定义的同名类, 这个类和单例对象存在于同一个文件中, 这个类就叫做这个单例对象的 ...
- scala 学习笔记(04) OOP(上)主从构造器/私有属性/伴生对象(单例静态类)/apply方法/嵌套类
一.主从构造器 java中构造函数没有主.从之分,只有构造器重载,但在scala中,每个类都有一个主构造器,在定义class时,如果啥也没写,默认有一个xxx()的主构造器 class Person ...
- Scala伴生类和伴生对象
单例对象与类同名时,这个单例对象被称为这个类的伴生对象,而这个类被称为这个单例对象的伴生类.伴生类和伴生对象要在同一个源文件中定义,伴生对象和伴生类可以互相访问其私有成员.不与伴生类同名的单例对象称为 ...
- Scala学习笔记(二):object、伴生对象和基本类
object object 是只有一个实例的类.它的定义与Java中的class类似,如: // 单例对象 object AppEntry { def main(args: Array[String] ...
- Scala单例对象和伴生对象
1.Scala单例对象 Scala单例对象是十分重要的,没有像在Java一样,有静态类.静态成员.静态方法,但是Scala提供了object对象,这个object对象类似于Java的静态类,它的成员. ...
随机推荐
- LeetCode 上最难的链表算法题,没有之一!
题目来源于 LeetCode 第 23 号问题:合并 K 个排序链表. 该题在 LeetCode 官网上有关于链表的问题中标注为最难的一道题目:难度为 Hard ,通过率在链表 Hard 级别目前最低 ...
- .NET CAD二次开发学习 直线画矩形并转换成组
主要代码: using System;using System.Collections.Generic;using System.Linq;using System.Text;using System ...
- 数据结构——Java实现链栈
一.分析 栈是限定仅在表的一端进行插入或删除操作的线性表,对于栈来说,操作端称为栈顶,另一端则称为栈底,栈的修改是按照后进先出的原则进行的,因此又称为后进先出的线性表. 链栈是指采用链式存储结构实现的 ...
- C++系列总结——封装
前言 众所周知,封装.继承和多态是面向对象编程的三大特性.C++作为一门面向对象的编程语言,自然支持了这些特性,但C++是如何实现这些特性的呢?今天先说下我理解的封装. 封装 通常我们会把下面的行为也 ...
- js中事件冒泡,事件捕获详解
一.事件流 事件是js与HTML交互的基础,事件流描述的是页面接受事件的顺序,而事件流又分为三个阶段:捕获阶段.目标阶段和冒泡阶段. 如果单纯的事件处理,事件捕获和事件冒泡二选一即可,导致两者并存的原 ...
- android activity的生命周期和启动模式
activity是android开发的基本中的基本每一个项目都会有activity.activity有自己的生命周期,在网上有很多博客和资料,在这里我也只是印证一下. 一个activity: 在打开a ...
- Android项目实战(五十二):控制EditText输入内容大小写转换
今日需求,EditText内容为一串字符串,要求将用户软键盘输入的小写字母在输入的时候自动转为大写字母,反之亦然. 效果如下: 第一次做该需求,原先想法: EditText.addTextChange ...
- Jmeter Beanshell 用法
Beanshell 的用法 什么是beanshell Beanshell是一种完全符合java语法的脚本语言,并且拥有自己的内置对象和语法 Beanshell是用java写的,一个小型嵌入式java源 ...
- SpringBoot Mybatis 使用LocalDateTime
mybatis-spring-boot-starter 2.0.1 会报错,不知道如何解决(建议先不用) mybatis-spring-boot-starter 2.0.1 - 1.3.2 版本不会报 ...
- RuntimeException和Exception区别
1.java将所有的错误封装为一个对象,其根本父类为Throwable, Throwable有两个子类:Error和Exception. 2.Error是Throwable 的子类,用于指示合理的应用 ...