接上篇
6.辅助构造器
有时一个类里需要多个构造器。Scala里主构造器之外的构造器被称为辅助构造器。比如,分母为1的有理数,直接写分子就行。即可以把类定义为一个参数,如下:
class Rational(n: Int, d: Int) {
require(d != 0)
val numer: Int = n
val denom: Int = d
override def toString = n + "/" + d
def this(n: Int)=this(n,1) //辅助构造器
def add(that: Rational): Rational = new Rational(numer * that.denom + that.numer * denom, denom * that.denom)
}
object Rational {
def main(args: Array[String]) {
val y = new Rational(3)
println(y)
}
}
打印出3/1
Scala辅助构造器定义开始于def this()。函数体几乎完全就是主构造器的调用。Scala里的每个辅助构造器的第一个动作都是调用同类的别的构造器,即每个辅助构造器都是以this(...)形式开头的。
7.私有字段和方法
在上面计算相加中,我们都没有没有做到简约化,都没有做到有理化,如val g =Rational(66,42),输出为66/42,最简形式应为11/7。下面实现消去公约数,实现有理化。
class Rational(n: Int, d: Int) {
require(d != 0)
private val g = gcd(n.abs, d.abs)
val numer = n / g
val denom = d / g
def this(n: Int) = this(n, 1)
def add(that: Rational): Rational = new Rational(numer * that.denom + that.numer * denom, denom * that.denom)
override def toString = numer + "/" + denom
private def gcd(a: Int, b: Int): Int = if (b == 0) a else gcd(b, a % b)
}
object Rational {
def main(args: Array[String]) {
val test = new Rational(66, 42)
println(test)
}
}
这里添加了私有字段g,并修改了numer和denom的初始化器。因为g是私有的,所以只能在类的主体之类被访问,外部不可见。abs是绝对值。
8.定义操作符
在scala里。整数和浮点数相加可以直接用+,但是有理数相加必须是x.add(y)。这里我们重新定义scala里的标示符‘+’和‘*’
class Rational(n: Int, d: Int) {
require(d != 0)
private val g = gcd(n.abs, d.abs)
val numer = n / g
val denom = d / g
def this(n: Int) = this(n, 1)
def +(that: Rational): Rational = new Rational(numer * that.denom + that.numer * denom, denom * that.denom)
def *(that: Rational): Rational = new Rational(numer * that.numer, denom * that.denom)
override def toString = numer + "/" + denom
private def gcd(a: Int, b: Int): Int = if (b == 0) a else gcd(b, a % b)
}
object Rational {
def main(args: Array[String]) {
val x = new Rational(1, 2)
val y = new Rational(2, 3)
println(x + y)
println(x * y)
}
}
输出为
7/6
1/3