Scala中的构造器与对象【文末加群学习哦】

前言

在《大数据之脚踏实地学19--Scala中类的使用》中我们详细介绍了Scala中类的使用,通过类的构造,借助于new关键词创建不同的实例化对象,进而实现代码的可复用性。在本期我们将继续介绍跟类相关的另外两个主题,即构造器和单例对象


构造器

通过上一期Scala类的介绍,我们会发现一个非常显著的特征,即给类实例化过程中,所传递的参数都是相同类型或相同个数。那么问题来了,有没有这样一种类,允许用户创建不同类型(即包含不同参数列表或参数类型)的实例化对象?答案是肯定有的。这种类就是我们接下来要介绍的构造器,构造器的另一个用途是可以方便地设定类的初始属性值。


首先,我们来看一下,Scala中构造器的语法结构

// 构造器的语法class ClassName[(Parameters List)] { // 主构造器  def this[(Parameters List)] { 第一个辅助构造器    this[(Parameters List)] // 调用主构造器      ... // 辅助构造器的其他属性和方法  }  def this[(Parameters List)] {  第二个辅助构造器    this[(Parameters List)] // 调用主构造器或辅助构造器      ... // 辅助构造器的其他属性和方法  }}

针对如上的构造器语法,有几点内容需要说明:

  • 构造器可分为主构造器和辅助构造器;

  • 主构造器中除了方法之外的所有代码都会被执行;

  • 辅助构造器的创建一定是以this关键词开头;

  • 辅助构造器是没有返回值的;

接下来通过两个具体的例子,解释Scala中构造器的使用。如下代码只构造了含义参数列表的主构造器。其中参数使用了三种修饰方法,即val、var和非val非var

// 创建一个主构造器class Friend(val name: String, var age: Int, education: String) {  println("这就是一个最简单的主构造器")}// 创建一个对象,指定代码执行的主入口object ConsDemo1 {  def main(args: Array[String]): Unit = {    // 创建类的实例对象    val friend1 = new Friend("张三",28,"硕士")    // val修饰的name变量可以访问,具有getter权限    println("朋友的名字为:" + friend1.name)     // friend1.name = "李四"  将会报错,因为val修饰的变量具有不可变性,不可以设置新值,无setter权限    // var修饰的age变量可以访问,具有getter权限    println("他的年龄为:" + friend1.age)     friend1.age += 1    // var修饰的age变量具有可变性,可以设置新值,有setter权限    println("他第二年的年龄为:" + friend1.age)     // println(friend1.education)  将会报错,当变量没有val或者var修饰是,该变量既不可以访问也不可以设置新值    // 如果使education字段具有getter权限和setter权限,可以在类内部将该变量重新赋值给新变量    println(friend1)  }}

结果输出

640?wx_fmt=png

通过如上代码可至,三种修饰方式的参数,各有不同的功能。val参数仅有getter权限,即理解为读权限;var参数包含getter权限和setter权限,即理解为可读可写权限;非val非var参数是没有读写权限的

在下面例子中,我们给类创建了主构造器和辅助构造器,其中辅助构造器的功能是计算税后收入。从代码的最后一部分可以看出,我们创建的两个实例化对象p2和p3时,给类Friend2传递了不同个数的参数。p2实际上调用的是类的主构造器,p3则调用的是类的辅助构造器。

// 创建包含主构造器和辅助构造器的类class Friend2(val name: String, var age: Int, education: String) {  var income: Int = _  // 变量初始化  // 通过重新赋值,用户可以对Education变量进行访问和设置  var Education = education   println("这就是一个最简单的主构造器")  // 创建辅助构造器  def this(name: String, age: Int, education: String,income:Int){    this(name,age,education)  // 调用主构造器    this.income = income // 参数赋值    var res=0.0    if (income <= 5000) {res = income - 0}    else if (income <= 17000) {res = (income - (210 + (income-8000)*0.1))}    else  {res = (income - (210 + 900 + (income-17000)*0.2))}    println(s"${name}的收入为${income},经过计算,他的税后收入为${res}")  }}// 创建一个对象,指定代码执行的主入口object ConsDemo2 {  def main(args: Array[String]): Unit = {    // 对Friend2类实例化    val p2 = new Friend2("张三",28,"硕士")    // 修改属性的值    p2.Education = "本科"  // 修改学历    println(f"${p2.name}的年龄为${p2.age},他的学历为${p2.Education}")    // 对Friend2类实例化    val p3 = new Friend2("张三",28,"硕士", 16500)  }}

结果输出

640?wx_fmt=png

单例对象

Scala中是没有静态属性和静态方法的(即没有类似于Java中的voild修饰符),如果需要构造静态属性或静态方法,可以使用object关键词实现该功能,即在Scala中创建单例对象。在作者看来,Scala中单例对象的最大好处是实例化对象时可以不用new关键词。

单例对象可以分为孤立对象和伴生对象两种,孤立对象是指在一个Scala脚本文件中,对象的名称与类的名称不一致,这样的对象是不能访问类中的私有属性或方法的;伴生对象则是指脚本文件中,对象的名称与类的名称完全一致,此时对象和类之间是可以互相访问对方的私有属性和方法的

接下来,我们通过一个简单的例子加以说明,代码如下:

// 创建一个与对象Person同名的半生类class Person(name:String){    println(s"${name}的编号为${Person.newId}.")    // Person.newId就是直接调用了伴生对象中的newId方法}// 创建一个与类Person同名的伴生对象  object Person{//  定义一个私有变量    private var lastid = 0//  定义一个私有方法    private def newId: Int ={      lastid += 1      lastid    }  }// 创建一个对象,指定代码执行的主入口object ObjectDemo {  def main(args: Array[String]): Unit = {    // 类的实例化    val person1 = new Person("张三")    val person2 = new Person("李四")  }}

结果输出

640?wx_fmt=png


结语

本期的内容就介绍到这里,下一期我们将介绍Scala中类的继承。如果你有任何问题,欢迎在公众号的留言区域表达你的疑问。同时,也欢迎各位朋友继续转发与分享文中的内容,让更多的人学习和进步。

640?wx_fmt=png

(如果二维码过期了,可加微信lsx19890717,拉群哦)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Sim1480

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值