7.3 封装和泛化
6.2 节介绍了一种名为渐进开发的程序编写方法,本节介绍另一种程序开发(program development)流程——封装和泛化,步骤如下。
(1) 在 main 或其他方法中编写几行代码,并进行测试。
(2) 如果能够正确运行,就将它们封装到一个方法中,并再次测试。
(3) 如果这个方法没问题,就将其中的字面量替换为变量和形参。
其中的第二步被称为封装(encapsulation),第 3 步被称为泛化(generalization)。
为演示这种流程,我们将开发几个显示乘法表的方法。下面的循环显示 2 的幂,这些幂值都显示在一行中:
int i = 1;while (i <= 6) {System.out.printf("%4d", 2 * i);i = i + 1;}System.out.println();
第 1 行初始化变量 i,这个变量将充当循环变量(loop variable):每次执行循环时,都将变量 i 的值加 1;循环在 i 为 7 后终止。
每次循环都显示 2 * i 的值,并在它前面添加空格,使结果为 4 字符宽。由于我们使用的是 System.out.printf,因此所有输出都显示在一行中。
循环结束后,我们调用 println 打印一个换行符,从而换到下一行。别忘了,输出在有些环境中要遇到换行符后才显示。
因此,上述代码的输出如下:
2 4 6 8 10 12
下一步是将这些代码“封装”到一个新方法中。这个方法类似于下面这样:
public static void printRow() {int i = 1;while (i <= 6) {System.out.printf("%4d", 2 * i);i = i + 1;}System.out.println();}
接下来,我们用一个形参 n 替换常量值 2。这一步被称为泛化,因为它让这个方法更通用(不那么具体)。
public static void printRow(int n) {int i = 1;while (i <= 6) {System.out.printf("%4d", n * i);i = i + 1;}System.out.println();}
如果用实参 2 调用这个方法,得到的输出将与前面相同。使用实参 3 调用这个方法时,输出如下:
3 6 9 12 15 18
下面是用实参 4 调用这个方法得到的输出:
4 8 12 16 20 24
至此你可能猜到了我们将如何显示乘法表:反复调用方法 printRow,但每次指定不同的实参。实际上,我们将用另一个循环来遍历所有行。
int i = 1;while (i <= 6) {printRow(i);i = i + 1;}
输出类似于以下这样:
1 2 3 4 5 62 4 6 8 10 123 6 9 12 15 184 8 12 16 20 245 10 15 20 25 306 12 18 24 30 36
printRow 中的格式说明符 %4d 确保了输出都是垂直对齐的,不管结果是个位数还是十位数。
最后,我们将第二个循环封装到一个方法中:
public static void printTable() {int i = 1;while (i <= 6) {printRow(i);i = i + 1;}}
编程时面临的挑战之一是如何将程序划分成多个方法,对初学者来说尤其如此。封装和泛化流程能够让你一边编程一边设计。
