Scala编程(第5版)
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

6.8 私有字段和方法

在前一版Rational类中,我们只是简单地用类参数nd分别初始化了字段numerdenom。因此,一个Rational对象的分子和分母可能会比需要的更大。比如,分数66/42可以被正规化成等效的简化格式11/7,但Rational类的主构造方法目前并没有这样处理:

要做到正规化,需要对分子和分母分别除以它们的最大公约数greatest common divisor)。比如,66和42的最大公约数是6。(换句话说,6是可以同时整除66和42的最大整数。)对66/42的分子和分母同时除以6,得到简化形式的11/7。示例6.3展示了一种实现方式。

示例6.3 带有私有字段和方法的Rational

在这个版本的Rational类中,我们添加了一个私有的字段g,并修改了numerdenom字段的初始化器(初始化器是初始化某个变量的代码。例如,用来初始化numer字段的“n / g”)。由于g字段是私有的,我们只能从类定义内部访问它,从外面访问不到。我们还添加了一个私有方法gcd,计算传入的两个Int参数的最大公约数。比如,gcd(12, 8)返回4。正如你在4.1节看到的,要把一个字段或方法变成私有的,只需要简单地在其定义之前加上private修饰符。这个私有的“助手方法”gcd的目的是将类的其他部分(在本例中是主构造方法)需要的代码抽取出来。为了确保g字段值永远是正值,我们传入类参数nd的绝对值。取得绝对值的方式是对它们调用abs方法,并且可以在任何Int参数上调用abs方法来得到其绝对值。

Scala编译器会把Rational类的3个字段的初始化器代码按照它们在代码中出现的先后次序编译到主构造方法中。也就是说,g字段的初始化器,即gcd(n.abs, d.abs),会在另外两个初始化器之前执行,因为在源码中它是第一个出现的。g字段会被初始化成该初始化器的结果,即类参数nd的绝对值的最大公约数。接下来,g字段被用在numerdenom字段的初始化器中。通过对类参数nd分别除以它们的最大公约数g,每个Rational对象都会被构造成正规化后的形式: