6.2 编写方法
初学者常常犯这样的错误,即在不尝试编译并运行的情况下就编写大量代码,然后再花大量的时间调试代码。我们认为渐进开发(incremental development)是一种更好的方法,这种方法的要点如下。
先编写一个能够运行的简单程序,再逐步修改。这样的话,无论什么时候出现错误,你都知道该检查哪些地方。
用变量存储中间值,以便能够用打印语句或调试器检查它们。
程序能够正确运行后再将多条语句合并为复合表达式(前提是这样不会导致程序更难理解)。
举个例子,假设你要根据两个点的坐标 (x1, y1) 和 (x2, y2) 计算它们之间的距离,可使用下面的公式:

首先要考虑的是,用 Java 编写 distance 方法会是什么样的呢?换而言之,输入(形参)是什么?输出(返回值)又是什么?在这个示例中,输入是两个点;而要表示这两个点,显而易见的方法是使用 4 个 double 值。返回值是距离,其类型也应为 double。
据此就可以编写这个方法的轮廓了,这种轮廓有时被称为存根(stub),其中包含了方法的特征标和一条 return 语句:
public static double distance(double x1, double y1, double x2, double y2) {return 0.0;}
这条 return 语句是一个占位符,在确保程序能够通过编译方面必不可少。当前,这个程序并没有做什么有用的事情,但添加更多代码前有必要对其进行编译,以便发现语法错误。
开发新方法前先考虑测试是一个不错的主意,能够帮助你搞明白如何实现这些方法。要测试方法,可在 main 中调用,并将样本值用作实参:
double dist = distance(1.0, 2.0, 4.0, 6.0);
坐标指定的两点间的水平距离为 3.0,垂直距离为 4.0,因此结果应为 5.0。测试方法时知道正确答案很有帮助。
存根通过编译后,我们就可以开始添加代码了——每次一行。每次修改后都再次编译并运行程序。无论什么时候出现错误,我们都很清楚该检查什么地方:添加的最后一行代码。
下一步是计算(x2 - x1)和(y2 - y1)的差值。我们将这些值分别存储在临时变量 dx 和 dy 中。
public static double distance(double x1, double y1, double x2, double y2) {double dx = x2 - x1;double dy = y2 - y1;System.out.println("dx is " + dx);System.out.println("dy is " + dy);return 0.0;}
其中的打印语句让我们能够检查这些中间值,它们应该分别为 3.0 和 4.0,确定它们正确后再继续添加代码。可在方法编写好后删除这些打印语句;类似这样的代码被称为脚手架(scaffolding),因为它们可以帮助你创建程序,却不是最终产品的组成部分。
下一步是计算 dx 和 dy 的平方和。为此可使用方法 Math.pow,但更简单的方式是将它们分别与自己相乘:
public static double distance(double x1, double y1, double x2, double y2) {double dx = x2 - x1;double dy = y2 - y1;double dsquared = dx * dx + dy * dy;System.out.println("dsquared is " + dsquared);return 0.0;}
同样,此时应编译并运行该程序,同时也要检查中间值——应为 25.0。终于,我们可以用 Math.sqrt 来计算并返回结果:
public static double distance(double x1, double y1, double x2, double y2) {double dx = x2 - x1;double dy = y2 - y1;double dsquared = dx * dx + dy * dy;double result = Math.sqrt(dsquared);return result;}
等编程经验更丰富后,你就可以一次编写并调试多行代码。即便如此,渐进开发也可为你节省大量的时间。
