2019-04-15

关键字:Scala 主构造器、Scala 辅助构造器、Scala 构造器的区别

本篇文章系笔者根据当前所掌握知识对 Scala 构造器的一些心得总结,不保证文章所述内容的绝对、完全正确性。


同 Java 一样,Scala 中的类的实例化过程也是从 构造器 开始的。只不过 Scala 中的构造器有两种

1. 主构造器

2. 辅助构造器

我们可以使用任一种构造器来实例化我们的类。不过,就本质上来说,主构造器 才是真正将我们的类实例化的构造器。下面我们就来简单探讨一下 Scala 中的这两种构造器的使用方式以及区别。

1、主构造器

在一个 Scala 类中,有且仅有一个主构造器。在我们对一个类实例化的时候,一定会调用主构造器,或显式调用或隐式调用的区别而已。下面的示例代码中红框部分即是主构造器的参数声明

带参主构造器

什么才是主构造器呢?

我们可以暂时把它理解成如上图所示那样,是一组直接跟在类名后面的参数列表。这个参数列表在声明的时候要注意了,没什么事最好不要漏掉 val / var 之类的声明符,漏掉的话,有可能它就不属于主构造器中的参数了。

那有的同学可能要问了:我在定义一个类的时候经常不带参数啊,一样跑的很 6 啊。就像下面这样

不带参数的主构造器

确实没错,以上两种类的定义都是各种没毛病的。但是同时每一个 Scala 类中都有且仅有一个主构造器。所以,到这里就要否决掉我们上面的那个 “暂时的理解” 了。主构造器是与类交织在一起的,它以一种你看不见摸不着但又事实存在的状态存在着。有一种简单的理解方式,我们可以直接把整个类体当成是主构造器。因为在一个类中,直接写在类体内的语句都属于主构造器的内容。还是拿上面的两个示例来说,那条 println 语句就会在主构造器被调用时执行。

那我们如何通过主构造器来实例化我们的类呢?直接 new 并传参就好了。

2、辅助构造器

Scala 对于辅助构造器的数量没有限制,我们可以在一个类中定义 0 ~ n 个辅助构造器。可以直接由辅助构造器来实例化一个类。我们甚至可以认为 Scala 的辅助构造器就是 Java 或者 C++ 中的普通构造器,因为它们之间的区别仅有以下两点

1. 构造器的名称统一为 this ;

2. 每一个辅助构造器都必须显式地调用其它辅助构造器或者主构造器。

以下是一个辅助构造器的示例代码

Scala 的辅助构造器

Scala 中辅助构造器的名称统一为 this ,不像 Java / C++ 是类名。据说这样做的目的是为了方便后续修改类名。

Scala 辅助构造器必须显式调用主构造器或者其它辅助构造器。在 Java 中只是多了一个隐式调用超类默认构造而已,也挺好理解的。记住就好了。

关于辅助构造器的使用,该怎么 new 就怎么 new 呗。我就懒得贴代码了,和 Java 是一样的。

主构造器与辅助构造器的番外知识

我们是否可以认为:无参的主构造器就是一个辅助构造器

通过实例我们可以知道:在没有定义主构造器的参数列表时,我们在辅助构造器中调用的 this() 就代表着我们在调用主构造器。而且,在我们没有声明主构造器的参数时,是无法声明一个无参的辅助构造器的。

上面就是一个提示辅助构造器重名的情况。通过上面的报错提示,我们知道了默认的主构造器的名称就是 this() ,和无参辅助构造器是一样的。那它们是不是就是同一种东西了?

笔者认为:不是!

笔者认为两种构造器在某种情况下只是刚好重名了而已。在主构造器没有定义参数列表时,它的名字只是刚好叫作 this() 而已。在定义了带一个 Int 型参数的主构造器时,它的名字也只是刚好叫作 this(Int) 而已。不能简单地就认为主构造器和辅助构造器是同一种东西。应该是有一种 “形似神不似” 的感觉在里头。这个比较抽象,大家体会一下即可,同时我也不保证说我的这个观点就一定是正确的。


这篇文章是秉承 够用就好 的原则来写的。其实关于这两种构造器,笔者这篇文章中还有好多知识点是没有提到的。不提是因为笔者认为对于一个初学者来讲,并不需要弄懂所有的知识点,一些主要的,能解决你工作中大多数问题的点弄会了就可以了。要想深入钻研,还得靠日常工作中的积累。

浅析 Scala 构造器的更多相关文章

  1. scala构造器实战

    父类 abstract class Event(val name:String) { var time:Long var content:String } 子类 private[spark] clas ...

  2. Scala编程--函数式对象

    本章的重点在于定义函数式对象,也就是说,没有任何可变状态的对象的类.作为运行的例子,我们将创造若干把分数作为不可变对象建模的类的变体.在这过程中,我们会展示给你Scala面向对象编程的更多方面:类参数 ...

  3. 6. Scala面向对象编程(基础部分)

    6.1 基本介绍 6.1.1 Scala语言是面向对象的 1) Java时面向对象的编程语言,由于历史原因,Java中海存在着非面向对象的内容:基本类型,null,静态方法等 2) Scala语言来自 ...

  4. Scala - 快速学习06 - 面向对象

    1- 类 1.1- 简介:类.方法及对象 类是用来创建对象的蓝图. Scala文件中包含的多个类之间,都是彼此可见的,不需要声明为public. 创建对象 定义好类以后,就可以使用new关键字来创建对 ...

  5. 【大数据】Scala学习笔记

    第 1 章 scala的概述1 1.1 学习sdala的原因 1 1.2 Scala语言诞生小故事 1 1.3 Scala 和 Java  以及 jvm 的关系分析图 2 1.4 Scala语言的特点 ...

  6. Scala总结

    Scala总结 ===概述 scala是一门以Java虚拟机(JVM)为目标运行环境并将面向对象和函数式编程的最佳特性结合在一起的静态类型编程语言. scala是纯粹的面向对象的语言.java虽然是面 ...

  7. Scala学习八——继承

    一.本章要点 extends,final关键字和Java一样 重写方法时必须使用override 只有主构造器可以调用超类的构造器 可以重写字段 二.扩展类 Scala扩展类和Java一样(使用ext ...

  8. Scala类和对象

    1.面向对象 Scala的类与java.C++的一些比起来更简洁,速度更快 对象:使用object关键字修饰的 类:使用class关键字修饰的new Person()实例对象 new类:类的实例(对象 ...

  9. Scala 面向对象(一):类与对象基础(一)

    1 如何定义类 [修饰符] class 类名 { 类体 } 定义类的注意事项 1)scala语法中,类并不声明为public,所有这些类都具有公有可见性(即默认就是public), 2)一个Scala ...

随机推荐

  1. 使用Aspose.Words将Word文档转换为Tiff格式图片文件

    用Aspose组件的优点是操作Word文档不需要安装Office就可以实现. 首先需要引用Aspose.Words.dll,链接地址:链接:https://pan.baidu.com/s/1rJvjp ...

  2. 基础知识:编程语言介绍、Python介绍、Python解释器安装、运行Python解释器的两种方式、变量、数据类型基本使用

    2018年3月19日 今日学习内容: 1.编程语言的介绍 2.Python介绍 3.安装Python解释器(多版本共存) 4.运行Python解释器程序两种方式.(交互式与命令行式)(♥♥♥♥♥) 5 ...

  3. glibc溢出提权CVE-2018-1000001总结

    遇到了好几个centos6.5,一直尝试想提权.暂未成功,靶机内核:2.6.32-696.18.7.el6.x86_64. glibc版本:ldd (GNU libc) 2.12 目前编译过程中都发现 ...

  4. SAP MM 明明已经扩展供应商到采购组织下,采购订单里还是报错?

    SAP MM 明明已经扩展供应商到采购组织下,采购订单里还是报错? 如下的PO 4400000069,处于HELD状态.ME22N试图保存它为一个正式的采购订单,报错说供应商没有在采购组织下维护, 使 ...

  5. 大华门禁SDK二次开发(一)-技术沟通

    项目中需要能够查询门禁信号和控制门禁设备,因此需要基于大华门禁SDK进行二次开发,开发语言C#.门禁开发中遇到了一些问题,经过与大华技术的邮件沟通也一一解决.做这个开发的时候,发现网上的资料比较少,想 ...

  6. Salesforce的对象和字段

    对象 Salesforce默认提供了很多功能,可以用于销售.市场开发.客服等.为了实现这些功能,Salesforce提供了一系列的标准对象,比如"客户"(Account).&quo ...

  7. C语言经典算法 - 多维矩阵转一维矩阵的代码

    下边内容内容是关于C语言经典算法 - 多维矩阵转一维矩阵的内容,应该能对码农也有好处. #include <stdio.h>#include <stdlib.h>int mai ...

  8. Jmeter、Java当double显示的数字过长时取消科学计数法显示

    今日,由于项目需要,使用Jmeter发送查询账户并不保存余额,经过交易后,进行运算后再次比对余额. 实施过程中获取了余额字段并赋值给一个double变量.变量进行运算后再与交易后的账户余额进行比对.这 ...

  9. RuntimeException和Exception区别

    1.java将所有的错误封装为一个对象,其根本父类为Throwable, Throwable有两个子类:Error和Exception. 2.Error是Throwable 的子类,用于指示合理的应用 ...

  10. Chrome 清除当前网站下的缓存

    打开开发者工具(F12),选择 Network--Disable cache 即可.需要清除某网站缓存时 F12 打开开发者工具就会自动清除这个网站的缓存,而不必清除所有网站的缓存了. 如评论中大佬所 ...