浅析 Scala 构造器

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) 而已。不能简单地就认为主构造器和辅助构造器是同一种东西。应该是有一种 “形似神不似” 的感觉在里头。这个比较抽象,大家体会一下即可,同时我也不保证说我的这个观点就一定是正确的。



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

原文地址:https://www.cnblogs.com/chorm590/p/scala_201904151541.html

时间: 2024-10-10 00:37:18

浅析 Scala 构造器的相关文章

scala构造器

package cn.itcast.scala.day2 /** * Created by ZhaoXing on 2016/6/27. *///跟类名交织在一起的叫 主构造器class Student (val name: String, var age: Int, faceValue: Double = 99.99, private var height: Int = 18) { private[this] var gender : String = null def show(): Uni

Scala基础:面向对象——类

类 (class) 类是对象的模板,通过构造类,能够使用new关键字声明一系列同结构的对象. Scala的一个源文件可以包含多个public类. 声明Person类: class Person{   var name : String = _   val age = 10   private[this] val gender = "male" } 说明: name字段被赋值为"_""_"即占位符.表示name被声明为String.但赋值为&quo

Scala编程--函数式对象

本章的重点在于定义函数式对象,也就是说,没有任何可变状态的对象的类.作为运行的例子,我们将创造若干把分数作为不可变对象建模的类的变体.在这过程中,我们会展示给你Scala面向对象编程的更多方面:类参数和构造函数,方法和操作符,私有成员,子类方法重载,先决条件检查,同类方法重载和自指向. 6.1 类Rational的式样书 一个,或许不怎么重要的,发现是数学上,分数不具有可变的状态.一个分数加到另外一个分数上,产生的结果是一个新的分数.而原来的数不会被“改变”.我们将在本章设计的不可变的Ratio

Scala总结

===概述 scala是一门以java虚拟机(JVM)为目标运行环境并将面向对象和函数式编程的最佳特性结合在一起的静态类型编程语言. scala是纯粹的面向对象的语言.java虽然是面向对象的语言,但是它不是纯粹的,因为java的基本数据类型不是类,并且在java中还有静态成员变量和静态方法.相反,scala是纯粹面向对象的,每个值都是对象,每个操作都是方法调用. scala也是一个成熟的函数式语言.函数式编程有两个指导思想:①函数是头等值,也就是说函数也是值,并且和其他类型(如整数.字符串等)

每天学一点Scala之class 构造器

A.scala中类的构造器分为: 主构造器 从构造器 B.  主构造器 参数列表,就写在类名后面: 主构造器内容:类里,除了字段定义和方法定义外的内容,就是主构造器的内容了. C.  从构造器 类里,以def this开头的,都是从构造器, 从构造器的第一行,必须调用主构造器,或者,调用其他从构造器:其实,就是限制,从构造器的第一行,必须是主构造器,主构造器是类的唯一入口点.

Scala 中的构造器

Scala中的构造器相较于Java比较特殊,分为两种:主构造器,从构造器.主构造器是和类中字段和方法的定义混合在一起的. 在Scala中,不需要像Java一样需要在类中定义一个与类名相同的方法来当作构造器. 主构造器的参数列表写在类名的后面,而构造器的内容,则直接写在类定义里面,所以说,一个Scala类里面,除了方法和字段的定义以外的代码,全都是主构造器的内容. class Fruit(n: String, w: Int) { val name = n val weight = w printl

Scala主构造器和辅助构造器

注:1.本文主要参考自<快学Scala>2.使用jd-gui反编译   Scala的构造方法跟Scala很相似,也可以有任意多的构造器.在Scala中构造器分为主构造器和辅助构造器 在Scala中可以包括一个主构造器和任意多个辅助构造器 主构造器 在Scala中,每个类都有主构造器.而且主构造器的定义是跟类定义交织在一起的. 主构造器的参数是直接放置在类名后面的,如下: class Person(val name:String,val age:Int) { //your code } 主构造器

Scala类的构造器与访问器

1.构造器 在Scala中,每个类都有一个主构造器.主构造器与类的定义交织在一起,如下: class Person ( private var _name: String, private var _age: Int) 主构造器会执行类定义中的所有语句.如下,println语句是主构造器的一部分,当类被实例化时,println语句会立即执行. class Person private( private var _name: String, private var _age: Int){ prin

Scala入门到精通——第十五节 Case Class与模式匹配(二)

本节主要内容 模式匹配的类型 for控制结构中的模式匹配 option类型模式匹配 1. 模式的类型 1 常量模式 object ConstantPattern{ def main(args: Array[String]): Unit = { //注意,下面定义的是一个函数 //函数的返回值利用的是模式匹配后的结果作为其返回值 //还需要注意的是函数定义在main方法中 //也即scala语言可以在一个函数中定义另外一个函数 def patternShow(x:Any)=x match { ca