和Java或C++一样,Scala可以有任意多的构造器。
不过Scala类有一个构造器比其他所有构造器都更为重要,它就是主构造器。
除了主构造器之外,类还可以有任意多的辅助构造器。
主构造器
在Scala中,每个类都有主构造器。主构造器并不以this方法定义,而是与类定义交织在一起。
交织在一起怎么理解呢?
就是说你定义好了类,就自动定义好了主构造器,并不用再额外定义了。
主构造器的参数列表放到了类名的后面(我们也可以直接叫它类参数列表)
当我们定义一个类class Person(val pname: String, page: Int){ ... } 的时候
这里自动创建的主构造器的参数列表是 (pname: String, page: Int)
我们定义在主构造器参数列表的参数,在编译的时候会编译成类的字段。
主构造器的方法体就是整个类体
实例化一个类时,类体(主构造函数)中所有可行的部分都会被执行,不管是函数调用还是表达式等等。
只是对于类的字段和方法声明而言是没有什么可执行的,它们只是声明而已。
当主构造器定义的时候,主构造器会将类定义{}里的所有语句执行一次。
示例
class Fruit(n: String, w: Int) { val name = n; val weight = w; println("This is a " + n); println("Weight = " + w); }
如果接下来定义一个Fruit对象
val apple = new Fruit("Apple", 10);
则会在屏幕上打印:
This is a Apple
Weight = 10
现在你是不是有疑问,参数在类的参数列表中定义和在类的方法体中定义又有什么不同呢?
其实本质没有任何的不同。因为在类参数列表中定义的参数会被编译成类的字段。
这就像是:在函数的参数列表中声明的参数和方法体中声明的变量本质上没有任何不同一样!
辅助构造器
辅助构造器同Java或C++的构造器十分相似,只有两处不同。
■ 辅助构造器的名称为this。在Java或C++中,构造器的名称和类名相同,当你修改类名时就不那么方便了
■ 每一个辅助构造器都必须以一个对先前已定义的其他辅助构造器或主构造器的调用开始
当我们调用第一个辅助构造器的时候,必须要先调用主构造器。
第二个辅助构造器可以调用第一个辅助构造器或者主构造器,依次类推。
因此主构造器是类的唯一入口点。
示例:
class Person { //没有任何类的参数,主构造器为() private var name="" ; private var age=0 ;
def this(name: String){ //一个辅助构造器 this(); // 调用主构造器 this.name=name ; }
def this (name: String,age: Int) { // 另一个辅助构造器 this (name) ;//调用前一个辅助构造器 this.age=age ; }
}
和Java、C++一一样,类如果没有显式定义主构造器则自动拥有一个无参的主构造器即可。你可以以三种方式构建对象:
val p1 = new Person //主构造器 val p2 = new Person("Fred")//第一个辅助构造器 val p3 = new Person ("Fred",42) //第二个辅助构造器