上一节讲到了scala中的主构造器,这一节讲一下scala中的辅助构造器。
辅助构造器的基本语法
class 类名(形参列表) { // 主构造器
// 类体
def this(形参列表) { // 辅助构造器
}
def this(形参列表) { //注意辅助构造器可以有多个
}
}
我们可以先来回顾一下java中构造器的定义
class Lion{
String color = "";
Double weight;
Lion(){
}
Lion(String color){
this.color = color;
}
Lion(Double weight ){
this.weight = weight;
}
Lion(String color,Double weight){
this(color);
this.weight = weight ;
}
}
java这种构造器其实在实际使用的使用会造成不少的麻烦,如在修改类名时构造函数名称也必须要修改,scala语法在一定程度上做了改进,即scala在定义辅助构造器时通过this关键字来解决这一问题。
object demo05 {
def main(args: Array[String]): Unit = {
new Teacher("tom").showInfo()
new Teacher("jack",18).showInfo()
new Teacher("mary",20,"woman").showInfo()
}
}
class Teacher{
var name : String = _
var age : Int = _
var sex : String = _
def this(inName : String){
this //调用的时前面无参主构造器,必须要先调用前面的主构造器,否则会报错
this.name = inName
}
def this(inName : String,inAge : Int){
this(inName) //调用的时前面的辅助构造器this(inName : String)
this.age = inAge
}
def this(inName : String,inAge : Int,inSex : String){
this(inName,inAge)
this.sex = inSex
}
def showInfo(): Unit ={
println("name:" + name + " age:" + age + " sex: " + sex)
}
}
程序的运行结果
name:tom age:0 sex: null
name:jack age:18 sex: null
name:mary age:20 sex: woman
代码中class Teacher后面没有参数,这其实是定义了一个无参的构造器,在类中分别通过def this(inName : String),def this(inName : String,inAge : Int),def this(inName : String,inAge : Int,inSex : String)定义了三个辅助构造器,辅助构造器通过this来定义,这一点上极大的解决了上述java构造器名字必须要和类名相同的问题,而且在类的内部也是通过this关键字来调用其他的辅助构造器,这点和java一样,注意在使用辅助构造器来创建对象时,可以直接通过类名并指定相应的参数来完成,编译器会根据参数的个数以及类型来决定调用哪个辅助构造器。
对Teacher类进行反编译后,生成如下的底层代码,可以看到一共生成了四个构造器,分别是Teacher(),Teacher(String inName),Teacher(String inName, int inAge),Teacher(String inName, int inAge, String inSex),其中Teacher为我们主构造器,其他三个为我们之前定义的辅助构造器。
public class Teacher
{
private String name;
private int age;
private String sex;
public String name()
{
return this.name; }
public void name_$eq(String x$1) { this.name = x$1; }
public int age() { return this.age; }
public void age_$eq(int x$1) { this.age = x$1; }
public String sex() { return this.sex; }
public void sex_$eq(String x$1) { this.sex = x$1; }
public void showInfo()
{
Predef..MODULE$.println(new StringBuilder().append("name:").append(name()).append(" age:").append(BoxesRunTime.boxToInteger(age())).append(" sex: ").append(sex()).toString());
}
public Teacher()
{
}
public Teacher(String inName)
{
this();
name_$eq(inName);
}
public Teacher(String inName, int inAge) {
this(inName);
age_$eq(inAge);
}
public Teacher(String inName, int inAge, String inSex) {
this(inName, inAge);
sex_$eq(inSex);
}
}
关于scala中辅助构造器中的默认参数
def this(inName : String = "dany",inAge : Int = 30 ,inSex : String){
this
this.name = inName
this.age = inAge
this.sex = inSex
}
调用的话需要指定一下参数的名字,例如new Teacher(inSex = "man").showInfo()
,如果不指定的话默认将参数作为第一个参数的值