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。