Scala 令人着迷的类设计
这篇博客深入介绍 Scala 的类的相关知识, 看看 Scala 简洁的类定义背后都发生了什么? 从简洁的 Scala 类定义代码到冗长的反编译代码解读之后, 回过头在去编写简洁的 Scala 代码时, 我相信这是一个奇妙的感觉.
尽管 Scala 和 Java 有很多相同的地方, 但是在类的声明, 构造, 访问控制上存在很大的差异, 通过本文你也能看到相比较 Java 很多啰嗦的模板代码, Scala 更加的简洁, 使用 Scala 之后, 我想你再也不想去编写那些冗长的 Java 代码了. 不过由于 Scala 写代码简化了很多东西(背后为我们编写很多模板代码), 如果你刚从 Java 转到 Scala, 会感觉有点不适应, 不过一旦你了解 Scala 类的知识, 你将会有不一样的感觉.
为了让你看清楚 Scala 类的全貌, 本文使用 Java Decompiler 反编译工具向你展现 Scala 代码反编译的结果, 这样 Scala 都做了什么你就一目了然了. 还有一点就是, JavaBean 中 一对 getter /setter 方法通常称为属性
, 由于 Scala 并没有遵循 JavaBeans 规范将字段属性定义为 getXXX, setXXX, 现在有各种中文版称呼, 现在还没有一个让我感到很舒服的称中文名称, 所以本文还是沿用 Java 中称呼, 用 setter 表示修改方法, getter 表示取值方法, 如果你从 Java 中转过来, 这样表示你将会感到很舒服.
本文以如下思路依次展现 Scala 类相关知识. 为了能避免理论上的空谈, 我们从代码入手, 这就要求我们先得有一个类, 所以我们先从类的主构造器入手, 看看 Scala 类的大致样子, 然后再介绍类的字段定义和访问控制, 方法可见性, 辅助构造器等相关知识, 下面, 我们先看看类的主构造器吧
1. 主构造器
如果你是从 Java 转到 Scala, 你马上就能发现 Scala 声明主构造函数的过程和 Java 区别很大; Java 中构造器函数的定义一目了然, 由于Scala 的设计者认为每敲一个键都是珍贵的, 所以把 Scala 主构造器的定义和类的定义交织在一起, 导致 Scala 的主构造器没法像 Java 的构造器那样清晰了. 当我们学习新知识时, 开放的心态是很重要的, 因为这样我们才能欣赏不同第一眼令我们困惑的设计蕴含的迷人的东西. 在看到下面的代码时, 如果你觉得困惑, 不妨以一种比较开放的思维来看待这样的设计, 想想这样设计给我们带来的代码上的简洁. Scala 之父 Martin Odersky 建议我们这样来看待主构造器, "在 Scala 中, 类也接受参数, 就像方法一样". 开始介绍技术上的知识:)
主构造器结构
先来说明 Scala 类一个术语的定义, 字段(Filed), 对应于 Java 中成员变量, 不过又有不同之处, Scala 中字段还对应一组 setter/getter 方法, 现在有疑问的话, 可以先当成员变量理解, 看到后面就懂了.
在 Scala 中, 每个类都有主构造器, 有如下的结构
- 主构造器的定义和类的定义交织在一起, 主构造器的参数被编译成字段;
- 主构造器会执行类定义中的所有语句;
- 如果类名后没有参数, 即该类具备一个无参主构造器, 这样的一个构造器仅仅简单的执行类体的所有语句而已
好的, 我们来看一个简单的 Flower 类, Flower 类体由 3 个字段, 1 个方法定义和调用语句, 以及 2 个 println 语句构成
class Flower(val name: String, var color: String) {
println("constructor start")
var number = 10
def showMessage = println(s"$number $color $name")
showMessage
println("constructor finish")
}
object Test extends App {
new Flower("lilac", "purple") // lilac 丁香花
}
/*输出
constructor start
10 purple lilac
constructor finish
*/
我们先来看看看上面的 Flower 类. 定义 Flower 类时, 我们直接在类名后加上了参数列表, 即主构造器的参数列表, 这是与 Java 的不同之处, 即上面说的第 1 个特点, 主构造器的定义和类的定义交织在一起, 并且这些由 val 或 var 定义的参数列表会成为 Flower 类的字段(成员变量); 接着, 我故意把 Flower
Scala 令人着迷的类设计的更多相关文章
- iOS控制器之基类设计
题记 在进入新公司后.经过这一个月的重构项目,终于把项目做到了个人相对满意的程度(还有一种不满意的叫老板的需求,提过多次意见也没用= =!).在这次重构中按照以前的思路设计出了个人觉得比较适用的一个基 ...
- 水果项目第1集-想法>需求->功能->数据库设计->类设计
懒,懒人,我是个懒人. 懒人想做点事,总是拖拖拉拉,迟迟没有开始. 很久很久以前,就想做属于自己的产品,但是至今还没有一个属于自己的产品. 两年前,终于想好,要做一个网上卖水果的系统,手机上点点,水果 ...
- [theWord] 一种英文字典的基类设计
theWord --- 一种英文字典的基类设计 使用场景 想写一个应用,来记录自己背单词时候,对每个单词的记忆状况之类的东西.至于为什么做这个,试过了一些背单词软件,并不觉得好用,自己做一个吧. 那么 ...
- YTU 2602: 熟悉题型——类设计( 矩形类定义【C++】)
2602: 熟悉题型--类设计( 矩形类定义[C++]) 时间限制: 1 Sec 内存限制: 128 MB 提交: 183 解决: 119 题目描述 定义一个矩形类,数据成员包括左下角和右上角坐标 ...
- Java 类设计技巧
摘自<Java核心技术>卷I:基础知识 p140 第4章对象与类 - 类设计技巧 1)一定将数据设计为私有. 最重要的是:绝对不要破坏封装性.有时候,需要编写一个访问器方法或更改器方法,但 ...
- 字体图标,盒子显隐,overflow属性,伪类设计边框,盒子阴影2d形变
字体图标 ''' fa框架: http://fontawesome.dashgame.com/ 下载 => 引入css文件 引入字体图标库 <link rel="styleshe ...
- Java11-java基础语法(十)类设计综合案例
Java11-java语法基础(十)类设计综合案例 一.类综合设计方法 1.类设计步骤 (1)分析数据成员 (2)分析成员方法和构造方法 (3)画出类图 (4)编码测试 2.具体问题 1)分析数据成员 ...
- JFreeChart绘制XY折线图(工具类设计)
准备用Java写通信的仿真平台作为毕业设计,相比matlab绘图,Java绘图需要自己去写很多工具类,博主在这采用了JFreeChart的开源解决方案,摸索着自己写了一个XY折线图工具类,话不多说贴源 ...
- iOS 基于MVC设计模式的基类设计
iOS 基于MVC设计模式的基类设计 https://www.jianshu.com/p/3b580ffdae00
随机推荐
- github用法小结
共享仓库 bare 裸仓库 生成裸仓库时必须以.git结尾. 仓库就相当于一个服务器 ### 创建远程仓库 1. 创建以.git结尾的目录mkdir repo.git 2 ...
- Oracle Database Transaction Isolation Levels 事务隔离级别
Overview of Oracle Database Transaction Isolation Levels Oracle 数据库提供如下事务隔离级别: 已提交读隔离级别 可串行化隔离级别 只读隔 ...
- QPS的计算方法
每秒查询率QPS是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准,在因特网上,作为域名系统服务器的机器的性能经常用每秒查询率来衡量. 原理:每天80%的访问集中在20%的时间里,这20%时 ...
- 使用dns批量管理普通主机名相关问题
1.dns配置 日常管理主机过程中,会有很多地方需要使用到主机名的,当主机非常多的时候,就不适合使用hosts来管理和同步的所有主机hosts了,这个时候就可以使用dns来管理主机名映射和变动 dns ...
- 【OGG】OGG基础知识整理
[OGG]OGG基础知识整理 一.GoldenGate介绍 GoldenGate软件是一种基于日志的结构化数据复制软件.GoldenGate 能够实现大量交易数据的实时捕捉.变换和投递,实现源数据库与 ...
- js实现类似iphone的秒表-添加平均数功能
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name ...
- java udp服务器设计源码
根据个人理解写的,轻喷. 没什么大的逻辑,直接上代码. UDPServer.java package mySocket;/* * 服务器端 */import java.awt.GridLayout;i ...
- 浅入深出之Java集合框架(下)
Java中的集合框架(下) 由于Java中的集合框架的内容比较多,在这里分为三个部分介绍Java的集合框架,内容是从浅到深,哈哈这篇其实也还是基础,惊不惊喜意不意外 ̄▽ ̄ 写文真的好累,懒得写了.. ...
- Java学习之路----计算圆形的面积和周长
题目:计算圆形的面积,其中圆形的半径是随意指定. 源代码以及所有的分析思路都如下: import java.util.Scanner; //引入Scanner类 public class TestAr ...
- CentOS 6.9上安装mysql-5.6.36
CentOS 6.9上安装mysql-5.6.36 1.准备数据存放的文件系统 新建一个逻辑卷,并将其挂载至特定目录即可.这里不再给出过程. 这里假设其逻辑卷的挂载目录为/data,而后需要创建/da ...