Scala构造器基本语法
Scala构造器和java一样,构造对象需要调用类的构造器,并且支持构造器重载(可以创建无数哥构造器) 和 java 不同的是 scala构造器分为 主构造器和辅助构造器
class 类名(形参列表){//主构造器
def this(形参列表){} //辅助构造器
def this(形参列表){}//辅助构造器
//类体
}
示例如下
class ConPerson private (inName:String,inAge:Int){
var name:String =inName
var age:Int =inAge
def this(name:String){
this("",0)//调用主构造器
this.name=name//重新赋值
}
def this(name:String,sex:String){
this("",0)//调用主构造器
this.name=name//重新赋值
}
//重写toString方法
override def toString: String = {
"name=["+name+"];age=["+age+"]"
}
println("主构造器会执行这句")
}
构造器注意事项
1)scala构造器的作用是完成对新对象的初始化工作,构造器没有返回值
2)主构造器声明直接放在类名后
3)主构造器会执行类定义块中的所有语句(这里可以体会到scala将面向对象编程和面向过程编程进行了融合,构造器就是方法)
4)如果主构造器没有参数,小括号可以省略 new A 等同于 new A()
5)辅助构造器名称为 this,多个时通过不同的形参列表进行重载,底层就是构造器重载
6)如果像让主构造器编程私有的,可以在()前加private ,扎样就只能通过辅助构造器构造对象了
7)辅助构造器的声明不能和主构造器一致否则编译不通过
ConPerson类反编译结果:
public class ConPerson
{
private String name;
private int age;
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 toString()
{
return 14 + "name=[" + name() + "];age=[" + age() + "]";
}
public ConPerson(String inName, int inAge)
{
this.name = inName;
this.age = inAge;
Predef..MODULE$.println("主构造器会执行这句");
}
public ConPerson(String name)
{
this("", 0);
name_$eq(name); }
public ConPerson(String name, String sex) {
this("", 0);
name_$eq(name);
}
}
构造器参数
构造器参数
1)如果主构造器的参数没有任何修饰符修饰,那么这个参数就只是个局部变量
2)如果主构造器参数使用val声明,那么 scala会将参数作为类的私有只读属性 (底层自动生成对应java属性)
3)如果主构造器参数使用var声明,那么scala会将参数作为类的成员属性使用,提供对应的*** 和 ***_$eq()方法。
代码示例
class ConPerson2 (var inName:String,val inAge:Int,inSex:String){
var name:String =inName
var age:Int =inAge
var sex:String =inSex;
println("主构造器会执行这句")
}
调用测试
val p2=new ConPerson2("李四",12,"男");
println(p2.inAge)
p2.inName="李四1"
反编译结果如下:
public class ConPerson2
{
private String inName;
private final int inAge;
private String name = inName();
private int age;
private String sex;
public String inName()
{
return this.inName; }
public void inName_$eq(String x$1) { this.inName = x$1; }
public int inAge() { return this.inAge; }
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 ConPerson2(String inName, int inAge, String inSex)
{
this.age = inAge;
this.sex = inSex;
Predef..MODULE$.println("主构造器会执行这句");
}
}
bean属性
javaBean规范定义了java的属性操作方式为 getXxx 和 setXxx。很多java框架都依赖这个命名习惯,
为了适应这些操作,Scala类字段增加 注解@BeanProperty时会为类自动生成规范的 get set方法,可以使用 setXxx 和 getXxx来读写属性
示例如下
class ConPerson2 (var inName:String,val inAge:Int,inSex:String){
@BeanProperty
var name:String =inName
var age:Int =inAge
var sex:String =inSex;
println("主构造器会执行这句")
}
调用代码
val p2=new ConPerson2("李四",12,"男");
p2.setName("ddd")
Scala对象创建流程
1)加载类信息(属性信息、方法信息)
2)在内存中开辟空间
3)使用父类构造器进行初始化
4)使用主构造器进行初始化
5)使用辅助构造器进行初始化
6)将对象引用赋值给变量
测试代码:
class P {
var pname:String =_;
println("父类构造器执行")
}
class S extends P {
var name:String =_;
var age:Int=_
def this(inName:String){
this()//调用主构造器
this.name=inName
//this.name=name//重新赋值
println("子类构辅助造器执行")
}
println("子类构主造器执行")
}
调用
var s1=new S("晓红")
print(s1.name)
输出结果:
父类构造器执行
子类构主造器执行
子类构辅助造器执行
晓红