构造器
Scala中构造器的分类
- 主构造器:在类中嵌入的一个构造器,最基本的一个构造器
- 只有1个
- 辅助构造器:为了方便实现构造器的重载而设计的
- 根据重载,可以定义多个
主构造器
Scala中主构造器的定义
- 规则:放在类名后面使用圆括号定义构造器中传递的参数,并且参数自动作为类的成员变量,不需要在类中定义
- 特点
- 主构造器与类交织在一起,主构造器的参数列表写在类名的后面
- 在类的内部除了成员变量和成员方法,其他所有代码都属于主构造器的一部分
代码实现
class Person01(var name:String = "itcast",var age:Int ) {
//成员属性
// var name:String = "itcast" //该属性在构造中被定义了,不需要重复定义
var country:String = "China"
var gender:String = "male"
// var age:Int = 19
//成员方法
def sayHello ()= println("Hello,Person ~")
}
object TestPerson01{
def main(args: Array[String]): Unit = {
//在类名的后面定义传递的构造参数
val p1 = new Person01("heima",18)
println(s"${p1.name} ${p1.country} ${p1.gender} ${p1.age}")
p1.sayHello()
//可以通过在主构造中指定默认值来实现无参构造实现
val p2 = new Person01(age = 18)
println(s"${p2.name} ${p2.country} ${p2.gender} ${p2.age}")
p2.sayHello()
}
}
辅助构造器
辅助构造器的规则
- 所有辅助构造器由方法来实现的,名称固定为this,可以进行重载多个,用于不同成员属性的构造
- 所有辅助构造器的方法体的第一行必须调用主构造器或者已存在的辅助构造器
辅助构造器的定义
def this(参数列表){
//第一行必须调用主构造器或者已存在的辅助构造器
}
实现
/**
* @ClassName Person01
* @Description TODO 实现辅助构造器的定义
* @Date 2021/4/13 8:18
* @Create By Frank
*/
class Person01(var name:String = "itcast" ) {
//成员属性
// var name:String = "itcast" //该属性在构造中被定义了,不需要重复定义
var country: String = "China"
var gender: String = "male"
var age: Int = 19
//成员方法
def sayHello() = println("Hello,Person ~")
//定义辅助构造器:this方法
def this(name: String, country: String) {
this(name)
this.country = country
}
def this(name:String,country:String,age:Int){
this(name,country)
this.age = age
}
}
object TestPerson01{
def main(args: Array[String]): Unit = {
//在类名的后面定义传递的构造参数
val p1 = new Person01("heima")
println(s"${p1.name} ${p1.country} ${p1.gender} ${p1.age}")
p1.sayHello()
//可以通过在主构造中指定默认值来实现无参构造实现
val p2 = new Person01
println(s"${p2.name} ${p2.country} ${p2.gender} ${p2.age}")
p2.sayHello()
//调用辅助构造器进行构造
val p3 = new Person01("bigdata","巴基斯坦")
println(s"${p3.name} ${p3.country} ${p3.gender} ${p3.age}")
p3.sayHello()
val p4 = new Person01("bigdata","巴基斯坦",100)
println(s"${p4.name} ${p4.country} ${p4.gender} ${p4.age}")
p4.sayHello()
}
}
流程总结
1)加载类信息(属性信息、方法信息)
2)在内存中开辟空间
3)使用父类构造器进行初始化
4)使用主构造器进行初始化
5)使用辅助构造器进行初始化
6)将对象引用赋值给变量
class Person {
var pname:String =_;
println("父类构造器执行")
}
class Student extends Person {
var name:String =_;
var age:Int=_
def this(inName:String){
this()//调用主构造器
this.name=inName
//this.name=name//重新赋值
println("子类构辅助造器执行")
}
println("子类构主造器执行")
}
//测试:
var student=new Student("张三")
print(student.name)
//输出结果
父类构造器执行
子类构主造器执行
子类构辅助造器执行
张三
语法糖
apply方法的功能
- 可以在实现构建Class的实例的时候,不用写new关键字
apply方法的实现
- 在伴生对象Object中定义apply方法,支持重载,必须返回Class的实例
- 当不写new时,编译器会自动判断,在伴生对象中寻找对应的apply方法,通过apply方法new对象来实现
- 设计思想:缩短函数与对象的距离,让函数成为对象,让对象可以像函数一样使用
代码实现
class Person02(var name:String) {
var age:Int = 20
//辅助构造
def this(name:String,age:Int){
this(name)
this.age = age
}
}
object Person02{
//传递一个参数,进行构造返回
def apply(name: String): Person02 = new Person02(name)
//传递两个个参数,进行构造返回
def apply(name: String,age:Int): Person02 = new Person02(name,age)
}
object TestPerson02{
def main(args: Array[String]): Unit = {
//通过正常的构造来实现对象构建
val p1 = new Person02("itcast")
val p2 = new Person02("itcast",30)
//通过语法糖来实现构造
val p3 = Person02("heima")
val p4 = Person02("heima",40)
}
}