7.4 再谈泛化
前面的 printTable 版本总是显示 6 行,我们可对其进行泛化,用形参替换字面量 6:
public static void printTable(int rows) {int i = 1;while (i <= rows) {printRow(i);i = i + 1;}}
下面是用实参 7 调用这个方法得到的输出:
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 367 14 21 28 35 42
这个版本更好,但还存在一个问题:每次显示的列数相同。要想进一步泛化,可给 printRow 再添加一个形参:
public static void printRow(int n, int cols) {int i = 1;while (i <= cols) {System.out.printf("%4d", n * i);i = i + 1;}System.out.println();}
现在 printRow 接受两个形参——n 和 cols,n 指定要计算哪个值的整数倍,而 cols 指定列数。因为我们给 printRow 添加了一个形参,所以还需要修改 printTable 中调用 printRow 的代码行:
public static void printTable(int rows) {int i = 1;while (i <= rows) {printRow(i, rows);i = i + 1;}}
这行代码执行时会将 rows(这里为 7)作为实参传递给 printRow。在 printRow 中,这个值被赋给 cols,这导致列数等于行数,因此得到的是一个 7×7 的方形表格:
1 2 3 4 5 6 72 4 6 8 10 12 143 6 9 12 15 18 214 8 12 16 20 24 285 10 15 20 25 30 356 12 18 24 30 36 427 14 21 28 35 42 49
合理地泛化方法常常会得到计划外的功能。例如,你可能注意到了,前面的乘法表是对称的,这是因为 ab=ba,所以这个表格中的每项都出现了两次。为节省油墨,可只打印这个表格的一半,为此只需要修改 printTable 中的一行代码:
printRow(i, i);
这使得每行的长度与其行号相同,结果是一个三角形乘法表:
12 43 6 94 8 12 165 10 15 20 256 12 18 24 30 367 14 21 28 35 42 49
泛化可让代码更通用、更易于重用甚至更容易编写。
