scala 系列之 08scala 类和构造器

教程 潘牛 ⋅ 于 2021-07-08 22:48:39 ⋅ 1589 阅读

9 类

​ 类和对象是Java、C++等面向对象编程的基础概念。类是用来创建对象的蓝图。定义好类以后,就可以使用new关键字来创建对象。

​ scala 如果不写权限修饰符,默认是public。

​ 一个类文件可以声明多个类;

定义语法:

//模板类
class 类名{
}
//单例对象--使用main(), 来测试
object 类名{
}

其中:

​ 类中可以放属性、方法、函数;

​ 类中属性的定义和变量的定义一样,用val 或 var 进行定义,默认权限是public;

​ 类中方法用关键字def 定义;

​ object对象,也称单例对象,该对象编译后都是静态成员;

​ 如果有同样一个类与该object名字一样,则称该object为该类的伴生对象,相对应,该类为object的伴生类;

类中的属性:

可以分为可变(var)和不可变(val)

访问修饰可以分 private 和 private[this]

示例:

package day02
class ClassDemo1 {
  // 定义可变的属性
  var name = "hainiu"
  // 地址:刚开始没值,后来给的值
  // 用_占位,刚开始的初始值和 定义属性类型一致,字符串默认是null
  // 当用 _占位,属性类型不可省略
  var addr:String = _
  // 定义不可变的属性
  val sex = "boy"
  // 定义方法
  def say = println("say hello")
  // 定义函数
  val printFunc = () => println(s"name:${name}, sex:${sex}")
}
object ClassDemo1Test{
  def main(args: Array[String]): Unit = {
    // 创建 对象
    val demo = new ClassDemo1
    println(demo.name)
    println(demo.sex)
    demo.say
    demo.printFunc()
//    demo.sex = "girl"
    demo.name = "hehe"
    demo.printFunc()
    // 字符串初始值是null
    println(demo.addr)
    demo.addr = "北京市昌平区"
    println(demo.addr)
  }
}

private 与 private[this]

用private修饰的属性,该属性属于对象私有变量,只有本类和伴生对象能访问到;

用private[this]修饰后,该属性属于对象私有变量,只有本类才能访问,伴生对象也访问不到;

package day02
class ClassDemo2 {
  val name:String = "翠花"
  // private 修饰的成员,伴生对象可访问,其他对象不可访问
  private val age:Int = 32

  // private[this] 修饰的成员,当前对象可用, 伴生对象、其他对象均不可访问
  private[this] val money:Double = 8.8
}
// class ClassDemo2 的伴生对象
object ClassDemo2{
  def main(args: Array[String]): Unit = {
    val demo = new ClassDemo2
    println(demo.name)
    println(demo.age)
//    demo.money
  }
}
object ClassDemo2Test{
  def main(args: Array[String]): Unit = {
    val demo = new ClassDemo2
    println(demo.name)
//    demo.age
//    demo.money
  }
}

10 构造器

用于对类进行属性的初始化,分为主构造器和辅助构造器;

10.1 主构造器

语法:

//参数可以有默认值
class 类名 [private] (参数列表){
}

其中:

1)定义类的时候,就定义了构造器。即:是()内的内容。

2)主构造器会执行类中定义的所有语句。

3)private 加在主构造器前面标识这个主构造器是私有的,外部不能访问这个构造器。

package day02
// 主构造器参数如果是var、val修饰的,那就是public
// var:可变, val:不可变
class ConDemo1(var name:String, val age:Int) {
}
object ConDemo1Demo{
  def main(args: Array[String]): Unit = {
    // 通过主构造器创建对象
    val demo = new ConDemo1("傻强", 10)
    println(s"name:${demo.name}, age:${demo.age}")
    demo.name = "奀妹"
//    demo.age = 10
  }
}

4)主构造器内的参数可以是默认值;当参数有默认值,且参数在后面时,创建对象时可以不用给参数赋值;

package day02
// 主构造器参数如果是var、val修饰的,那就是public
// var:可变, val:不可变
class ConDemo1(var name:String, val age:Int=10) {
}
object ConDemo1Demo{
  def main(args: Array[String]): Unit = {
    // 通过主构造器创建对象
//    val demo = new ConDemo1("傻强")
    val demo = new ConDemo1("傻强", 11)
    println(s"name:${demo.name}, age:${demo.age}")
    demo.name = "奀妹"
//    demo.age = 10
  }
}

5)主构造器内的参数可以用var、val修饰,也可以不加 var、val 修饰

​ a)var 修饰的参数,可以在其他类中访问和修改;

​ b)val 修饰的参数,只可以在其他类中访问,但不能修改;

​ c)不加 var、val 修饰的参数,就相当于被private [this] val 修饰,不可以在其他类中访问和修改;

// 如果主构造器的参数没有var、val 修饰代表private[this]
class ConDemo2(var name:String, val age:Int=10, addr:String = "四川") {
  def printInfo = println(this.addr)
}
object ConDemo2{
  def main(args: Array[String]): Unit = {
    val demo = new ConDemo2("傻强")
    println(s"name:${demo.name}, age:${demo.age}")
//    demo.addr
  }
}
object ConDemo2Demo{
  def main(args: Array[String]): Unit = {
    // 通过主构造器创建对象
    val demo = new ConDemo2("傻强")
    println(s"name:${demo.name}, age:${demo.age}")
//    demo.addr
    demo.printInfo
  }
}

10.2 辅助构造器

赋值构造器的名称是 this;

辅助构造器可以理解成java中的构造器重载,且辅助构造器的第一行必须要先调用主构造器(这点和python 的基础调用父类比较相似);

辅助构造器可以没有,如果有要在类中进行定义,辅助构造器可以声明主构造器没有的参数,可以通过辅助构造给属性赋值;

辅助构造器的参数不能用val或者var修饰,因为其参数都是参考主构造器或者类中的;

package day02
class ConDemo3(val name:String) {
  var age:Int = _
  var addr:String = _
  // 通过辅助构造器实现scala的构造器重载
  // 辅助构造器的名字:this
  // 把this当做方法,传参不能有var、val修饰
  // 构造器的第一句需要 调用主构造器
  // 给属性赋值,属性的存在
  def this(name:String, age:Int) = {
    this(name)
    this.age = age
  }
  def this(name:String, age:Int, addr:String) = {
    this(name)
    this.age = age
    this.addr = addr
  }
// 辅助构造器不能和主构造器参数类型一致
//  def this(name:String) = {
//    this(name)
//  }
}
object ConDemo3{
  def main(args: Array[String]): Unit = {
    // 通过主构造器创建对象
    val demo = new ConDemo3("hainiu")
    println(demo.name)
    // 通过辅助构造器创建对象
    val demo2 = new ConDemo3("hainiu", 10)
    println(s"name:${demo2.name}, age:${demo2.age}")
    // 通过辅助构造器创建对象
    val demo3 = new ConDemo3("hainiu", 10, "北京")
    println(s"name:${demo3.name}, age:${demo3.age},addr:${demo3.addr}")
  }
}

10.3 总结

主构造器

1)主构造器的参数列表要放到类名的后面,和类名放在一起,val修饰的构造参数具有不可变性,var修饰的构造参数具有可变性;

2)如果参数没有用val或var修饰,那它不可被外面直接访问(可通过相应的get方法访问),只能在本类中使用;

3)如果参数没有用val或var修饰,伴生对象也无法使用(相当于用private[this]),也不可在本类中进行修改,因为它被当成隐藏的val修饰的;

辅助构造器

1)辅助构造器可以没有;如果有,要在类中进行定义。

2)辅助构造器可以声明主构造器没有的参数,如果声明了其它参数那这个参数需要在类中进行定义,否则提示无法找到这个参数;

3)辅助构造器的参数不能用val或者var修饰,因为其参数都是参考主构造器或者类中的;

4)辅助构造器也可以理解成java中的构造器重载,且辅助构造器的第一行必须要先调用主构造器(这点和python的子类调用父类比较相似,而JAVA可以选择是否调用默认构造器)

idea使用:

如果按ctrl+p,提示有两行或多行的时候那就说明有辅助构造器;

快捷键修改

settings → Keymap,在搜索框输入 “parameter info”, 然后双击搜索结果“parameter info”,选择添加快捷键,再点applay → ok。

file

版权声明:原创作品,允许转载,转载时务必以超链接的形式表明出处和作者信息。否则将追究法律责任。来自海汼部落-潘牛,http://hainiubl.com/topics/75743
成为第一个点赞的人吧 :bowtie:
回复数量: 0
    暂无评论~~
    • 请注意单词拼写,以及中英文排版,参考此页
    • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`, 更多语法请见这里 Markdown 语法
    • 支持表情,可用Emoji的自动补全, 在输入的时候只需要 ":" 就可以自动提示了 :metal: :point_right: 表情列表 :star: :sparkles:
    • 上传图片, 支持拖拽和剪切板黏贴上传, 格式限制 - jpg, png, gif,教程
    • 发布框支持本地存储功能,会在内容变更时保存,「提交」按钮点击时清空
    Ctrl+Enter