6.7 辅助构造方法
有时需要给某个类定义多个构造方法。在Scala中,主构造方法之外的构造方法称为辅助构造方法(auxiliary constructor)。例如,一个分母为1的有理数可以被更紧凑地直接用分子表示,如5/1可以被简单地写成5。因此,如果Rational类的使用方可以直接写Rational(5)而不是Rational(5, 1),则可能是一件好事。这需要我们给Rational类添加一个额外的辅助构造方法,只接收一个参数,即分子,而分母被预定义为1。示例6.2给出了相关代码。
Scala的辅助构造方法以def this(...)开始。Rational类的辅助构造方法的方法体只是调用一下主构造方法,透传它唯一的参数n作为分子,1作为分母。可以在编译器中输入如下代码来实际观察辅助构造方法的执行效果:
示例6.2 带有辅助构造方法的Rational类
在Scala中,每个辅助构造方法都必须首先调用同一个类的另一个构造方法。换句话说,Scala每个辅助构造方法的第一条语句都必须是这样的形式:“this(...)”。被调用的这个构造方法要么是主构造方法(就像Rational示例那样),要么是另一个出现在发起调用的构造方法之前的另一个辅助构造方法。这个规则的净效应是Scala的每个构造方法最终都会调用该类的主构造方法。这样一来,主构造方法就是类的单一入口。
注意
如果你熟悉Java,则可能会好奇为什么Scala的构造方法规则比Java更严格。在Java中,构造方法要么调用同一个类的另一个构造方法,要么直接调用超类的构造方法。而在Scala中,只有主构造方法可以调用超类的构造方法。Scala这个增强的限制实际上是一个设计的取舍,用来换取更精简的代码和与Java相比更为简单的构造方法。我们将会在第10章详细介绍超类,以及构造方法和继承的相互作用。