基础简介
Scala创建对象时可以调用构造方法,并且Scala可以有任意多个构造方法(相当于重载操作);在Scala中构造器包括主构造器与辅助构造器。
主构造器
每一个类都会有主构造器,主构造器并不是以this方法进行定义的,而是与类定义交织在一起。
object MainCon {
def main(args: Array[String]): Unit = {
val worker1 = new Worker("smith")
worker1.name
}
}
class Worker(inName: String) { // 这就是Worker类的主构造器
var name = inName
}
辅助构造器
每个类可以有多个辅助构造器,相当于Java中构造器的重载,函数的名称为this,编译器通过不同的参数来区分不同的辅助构造器。
object AssistCon {
def main(args: Array[String]): Unit = {
val p = new Person("zhangsan",20) // 这就是通过name,age两个参数的辅助构造器创建的实例
p.showInfo()
}
}
class Person {
var name: String = _
var age: Int = _
// 辅助构造器
def this(name: String) {
// 辅助构造器无论是直接还是间接,最终都一定要调用主构造器,执行主构造器的逻辑
this()
this.name = name
}
// 辅助构造器
def this(name: String, age: Int) {
this() // 直接调用主构造器
this.name = name
this.age = age
}
def showInfo(): Unit = {
println("name:" + name)
println("age:" + age)
}
}
构造器使用注意事项
1,主构造器的声明直接放在了类名的后面
2,主构造器会执行类定义中的所有语句
class Person(val name: String, val age: Int) {
println("just constructed")
def desc = name + " is " + age + "years old"
}
// println语句是主构造器的一部分,每当有对象实例被构建时,上诉代码就会被执行
3,辅助构造器的名称为this,多个辅助构造器通过不同的参数列表进行区分,底层使用的就是构造器重载。
class Person {
var name: String = _
var age: Int = _
// 辅助构造器
def this(name: String) {
this()
this.name = name
}
// 辅助构造器
def this(name: String, age: Int) {
this() // 直接调用主构造器
this.name = name
this.age = age
}
}
4,辅助构造器无论是直接还是间接,最终都一定要调用主构造器,执行主构造器的逻辑。
class Dog {
var name: String = _
var age: Int = _
// 辅助构造器
def this(name: String) {
this() // 这里就是调用了主构造器
this.name = name
}
}
5,辅助构造器的声明不能和主构造器的声明一致,不然会发生错误。
构造器形参的使用
1,Scala中的主构造器的形参未使用任何修饰符修饰,这个参数就是局部变量
class Worker1(inName: String) { // 这个inName参数就是局部变量
var name = inName
}
反编译代码
public class Worker1
{
private String name;
public String name()
{
return this.name; }
public void name_$eq(String x$1) { this.name = x$1; }
public Worker1(String inName) { this.name = inName; } // 这个inName参数就是局部变量
}
2,如果参数使用了val关键字声明,那么Scala会将参数作为类的私有只读属性使用
class Worker2(val inName: String) { //这个inName参数就是个私有只读属性
var name = inName
}
反编译代码
public class Worker2
{
private final String inName; // 私有不可变属性
private String name;
public String inName()
{
return this.inName; }
public String name() { return this.name; }
public void name_$eq(String x$1) { this.name = x$1; }
public Worker2(String inName) { this.name = inName; }
}
3,如果参数使用var关键字声明,那么Scala就会将参数作为类的成员变量使用,同时提供对应的xxx()与xxx_$eq()方法,这个时候的属性是可以读写的。
class Worker3(var inName: String) {
var name = inName
}
反编译代码
public class Worker3
{
private String inName; //私有成员变量
private String name = inName();
public String inName()
{
return this.inName; }
public void inName_$eq(String x$1) { this.inName = x$1; }
public String name() { return this.name; }
public void name_$eq(String x$1) { this.name = x$1; }
public Worker3(String inName)
{
}
}