0%

scala构造器

scala构造器

scala与java相似,也存在构造器,且同样的一个类可以有多个构造器,支持构造器的重载,在构造对象时需要调用构造器,但是与java不同的是scala分为主构造器和辅助构造器

语法

1
2
3
4
5
6
7
8
9
10
11
// 这里的形参列表可以用var|val来修饰,默认是val的,即只读,不过一般没有必要用var
class 类名(形参列表) { // 主构造器
// 类体
// 可以有多个辅助构造器,函数名称都为this,根据不同的参数来区分(java的构造器重载)
def this(形参列表) { // 辅助构造器
// 辅助构造器必须在第一行显式(直接或间接)的调用主构造器
}
def this(形参列表) { //辅助构造器
// 辅助构造器必须在第一行显式(直接或间接)的调用主构造器
}
}

主构造器

主构造器的声明直接放置于类名之后,主构造器会执行类定义中的所有语句,即:构造器也是方法(函数),传递参数和 使用方法和前面的函数部分内容没有区别,主构造器只能有一个

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

1
2
3
4
5
6
7
8
9
// 如果主构造器没有参数,则()可省略
class Person(var inName: String, val inCardNo: String) { // 主构造器,主构造器只能有一个

private var name:String = inName
private var cardNo:String = inCardNo

println("构造器")

}

编译之后

1
2
3
4
5
public Person(final String inName, final String inCardNo) {
this.name = inName;
this.cardNo = inCardNo;
Predef$.MODULE$.println((Object)"构造器");
}

可以看到class中的所有东西都会变成构造器中的内容

私有化主构造器

如果主构造器想要进行私有化在参数列表前加上private

1
2
3
4
5
6
7
8
9
10
class Person private(inName: String, inCardNo: String) { // 主构造器,主构造器只能有一个

private var name:String = inName
private var cardNo:String = inCardNo
private var sex:String = _


println("构造器")

}

辅助构造器

辅助构造器是可以有多个的,且辅助构造器的第一行必须显式(直接或间接)的调用主构造器(这里是为了使用主构造器去调用父类的构造器,相当于java中每个构造器第一行都会使用super去调用父类构造器一样)

scala中只有主构造器可以调用父类的构造器,辅助构造器不能直接调用父类的构造器,在构造器中不能使用super()来调用父类构造器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Person(inName: String, inCardNo: String) { // 主构造器,主构造器只能有一个

private var name:String = inName
private var cardNo:String = inCardNo
private var sex:String = _


println("构造器")

def this(name:String,cardNo:String,sex:String){ // 辅助构造器可以有多个
// 辅助构造器第一行必须显式的调用主构造器
this(name,cardNo)
this.sex = sex
println("辅助构造器")
}

}

编译成java之后

1
2
3
4
5
6
7
8
9
10
11
public Person(final String inName, final String inCardNo) {
this.name = inName;
this.cardNo = inCardNo;
Predef$.MODULE$.println((Object)"构造器");
}

public Person(final String name, final String cardNo, final String sex) {
this(name, cardNo);
this.sex_$eq(sex);
Predef$.MODULE$.println((Object)"辅助构造器");
}

Bean

很多的java框架都已经习惯了getter/setter方法的命名习惯了,而scala默认生成的方法java框架是不识别的,为了与java的互操性,scala提供了@BeanProperty来生成getter/setter方法,将scala字段加上@BeanProperty可以像javaBean一样,生成规范的getter/setter方法

1
2
3
4
5
6
7
8
9
10
class Person private(inName: String, inCardNo: String) { // 主构造器,主构造器只能有一个

@BeanProperty var name:String = inName
@BeanProperty var cardNo:String = inCardNo
@BeanProperty var sex:String = _


println("构造器")

}