有些时候一个类里需要多个构造器。Scala里主构造器之外的构造器被称为辅助构造器。比方说,分母为1的有理数只写分子的话就更简洁。因此,Rational(5,1)简写成Rational(5)或许感觉会更好些。而这就需要给Rational添加只传入分子的辅助构造器并预先设定分母为1。如例:
package scalaTest
class Rational(n:Int,d:Int) {
require(d != 0)
val number:Int = n
val denom:Int = d
def this(n:Int) = this(n,1) //辅助构造器
override def toString = number + "/" + denom
def add(that:Rational):Rational = {
new Rational(number * that.denom + that.number * d , d * that.denom)
}
def lessThan(that:Rational) = {
this.number * that.denom < that.number * this.denom
}
def max(that:Rational) = {
if(this.lessThan(that)) that else this
}
}
Scala的辅助构造器定义开始于def this(....)。函数主体几乎完全是主构造器的调用,并传递了参数n做分子和1做分母。Scala里的每个辅助构造器的第一个动作都是调用同类其它的构造器。换句话说就是,scala类的每个辅助构造器都是以“this(......)”形式开头的。被调用的构造器既可以是主构造器,也可以是其它已定义的辅助构造器。规则的根本结果就是每个scala的构造器调用终将结束于对主构造器的调用,因此主构造器是类的唯一入口点。
注意
若熟悉java,你或许会奇怪为什么scala构造器的规则比java的还要严格。Java里构造器的第一个动作只有两个选择:要么调用同类的其他构造器,要么直接调用超类的构造器。Scala类里面只有主构造器可以调用超类的构造器。Scala里这种严格的限制实际上是为了让scala的构造器与java构造器相比更为清晰和简洁而付出的代价。