1.6 函数(在Java中称为“方法”更好)
Android游戏开发详解
让我们将目前为止所学到的所有内容组合起来,并且讨论编程的一个重要方面,即函数。
函数是一组规则。特别地,函数应该接受一个值并且输出一个相应的结果。以一个数学函数为例。
f(x)=3x +2
输入是任意的数值x,输出是3x +2的结果
例如,f(1)=3(1)+2=5
在Java中,我们可以定义一个非常类似的函数。如下的函数将接受一个float类型的输入,并且输出计算3x+2的结果。
程序清单1.6 Java函数
1 float firstFunction (float x) {
2 return 3*+ 2;
3 }
现在,我们来进一步看看如何编写一个Java函数(也叫作方法,具体原因我们在下一章中介绍)。要编写一个Java函数,首先声明返回值的类型。还要给函数一个名称,例如,firstFunction。在函数名称后面的圆括号中,列出所有必需的输入。
开始花括号和结束花括号,表明函数从哪里开始以及函数在哪里结束。如果这还不够形象化,这么做会有所帮助:想象一下,以花括号作为对角线形成一个矩形,将函数包围起来,如图1-3所示。这有助于你确定每个函数从哪里开始以及从哪里结束。
程序清单1.7展示了如何在代码中使用函数。注意,我们假设在代码中某处定义了一个名为firstFunction的函数,并且其行为就像程序清单1.6所描述的那样。
程序清单1.7 使用函数
1 // 1. declare a new float called input
2 float input = 3f;
3 // 2. declare a new float called result and initialize it with the
4 // value returned from firstFunction(input);
5 float result = firstFunction(input);
6 // 3. print the result
7 print(result);
程序清单1.7的输出如下。
11.0
1.6.1 函数调用概览
程序清单1.7的第5行有着某种魔力。让我们具体讨论这里发生了什么。通常,我们总是必须先计算赋值操作符的右边。计算这个表达式,涉及调用程序清单1.6中所定义的函数。当调用firstFunction的时候,程序将会进入到程序清单1.6中的函数定义,传入参数input。在firstFunction中,接受input的值并且将其复制到一个名为x的临时的局域变量(local variable)中,并且该函数向调用者(caller)返回3x + 2的值(在第5行)。这个返回值可以存储为一个变量,这正是我们使用result所做的事情。然后程序继续进行,打印出该返回值。
1.6.2 参数的更多讨论
函数可能接受多个输入,甚至是没有输入。在函数定义中,我们必须列出想要让函数接受的所有的输入,通过为每个想要的输入声明一个临时的局域变量来做到这一点。这些必需的输入,每一个都可以称为参数(parameter),其示例参见程序清单1.8。
程序清单1.8 函数声明
1 // Requires three integer inputs.
2 int getScore(int rawScore, int multiplier, int bonusScore) {
3 return rawScore * multiplier + bonusScore;
4 }
5
6 // Requires no inputs.
7 float getPi() {
8 return 3.141592f;
9 }
无论何时调用一个函数,你都必须传入在圆括号之间列出的所有的参数。例如,在程序清单1.8中,函数getScore声明了3个整型变量。你必须传入相应的值,否则的话,程序将无法运行。类似地,只有当你不传入任何参数的时候,函数getPi才会工作。
如前面所述,当我们把一个变量当作参数传递给函数的时候,只有其值(value)可以供函数使用(这个值是复制的)。这意味着,下面的程序清单1.9和程序清单1.10都将打印出相同的值15 700(根据程序清单1.8第3行所给出的公式)。
程序清单1.9 使用变量来调用getScore
1 int num1 = 5000;
2 int num2 = 3;
3 int num3 = 700;
4 print(getScore(num1, num2, num3));
程序清单1.10 使用直接编码的值来调用getScore
1 print(getScore(5000, 3, 700));
在程序清单1.9中,我们使用变量调用了getScore函数。注意,由于我们通过值来传递参数,参数的变量名无关紧要。它们不一定必须要和函数定义中的局域变量的名称一致。程序清单1.10没有使用变量,而是传递了直接编码(hardcoded)的值。
当然,在我们编写的大多数程序中,像getScore这样的函数,其参数都会根据用户执行和使用的习惯而改变,因此,我们通常要避免直接编码字面值。
1.6.3 函数小结
总的来说,要使用一个函数,我们必须做两件事情:首先,必须声明函数定义(如程序清单1.6所示);其次,必须调用该函数(如程序清单1.7所示)。如果想要让函数访问某些外部的值,我们会传递参数。函数返回的值拥有某种类型,这在声明函数的时候必须明确地声明,并且,可以使用相应的变量类型和赋值运算符来存储该值。
让我们再来看一个函数。
程序清单1.11 还活着吗?
1 boolean isAlive (int characterHealth) {
2 return characterHealth > 0;
3 }
作为练习,请尝试回答如下的问题(答案在后面给出)。
Q1: 程序清单1.11中的函数的名称是什么? 。
Q2: 程序清单1.11中的函数返回一个什么类型的值? 。
Q3: 程序清单1.11中的函数接受几个输入? 。
Q4: 列出该函数的所有的输入的名称: 。
Q5: isAlive(5)的结果是true还是false? 。
Q6 isAlive(-5) 的结果是true还是false? 。
Q7: isAlive(0) 的结果是true还是false? 。
如果你感到迷惑,不要失望!需要花一些时间,才能够完全理解函数。如果你对函数还不是完全清楚,随着在本章中看到更多的示例,以及在第2章中开始编写自己的函数,你会对函数有更深的认识。
上述问题的答案是:Q1: isAlive,Q2: boolean,Q3: 一个,Q4: characterHealth,Q5: true,Q6: false,Q7: false。