如前所述,实例变量和方法组成了类.目前为止,Vehicle类只包含了数据,却没有方法.尽管只有数据的类也是完全有效的,但是多数类具有方法.方法是操作类定义的数据,以及多数情况下提供对数据的访问的子例程.多数情况下,程序的其他部分都是通过类的方法来与类进行交互的.
一个方法包含一条或多条语句.在编写完善的Java代码中,每个方法只执行一项任务.每个方法只有一个名称,而方法也是通过使用这个名称被调用的.总之,可以对方法任意命名.但是,要切记main()是为程序开始执行的方法准备的,而且也不能使用Java关键字做为方法名.
当用文本表示方法时,使用编写Java的常用惯例,即在方法名称后面使用圆括号.例如,如果方法名为getval,那么在句子中使用他的名字时,就会写为getval(),这种表示方法有助于将书中的方法名和变量名区分开来:
ret-type name(parameter-list) { //body of method }
其中,ret-type指定方法返回的数据类型.返回类型可以是任何有效类型,包括创建的类类型.如果方法不返回值,返回类型必须为void.方法名由name来指定.该名称可以是任何合法的,并且是当前作用域没有被其他方法使用的标识符.parameter-list是一系列用逗号隔开的类型与标识符对.形参(parameter)本质上是调用方法时接收传递到方法的实参(argument)的值的变量.如果方法没有形参,形参列表就为空.
向Vehicle类添加方法
如前所述,类的方法通常操作类的数据或提供对类的数据的访问.知道这一点后,回想一下,在前面的实例中,我们通过将耗油率和油箱容量相乘来计算汽车的行驶里程的main().尽管技术上这是正确的,但这不是处理这种计算的最佳方法.计算汽车的行驶里程最好由Vehicle类自己来处理.这一结论的原因是易于理解:汽车的行驶里程与油箱容量以及燃油率有关,这两个数据都被封装在Vehicle类中.通过向Vehicle类添加一个计算行驶里程的方法,可以增强他的面向对象结构.要想向Vehicle添加一个方法,在Vehicle的声明内指定他即可.例如,下面的Vehicle版本就包含一个名为range的方法,他显示汽车的里程:
public class test { // @param args public static void main(String args[]) { Vehicle minivan = new Vehicle(); Vehicle sportscar = new Vehicle(); int range1,range2; minivan.passengers = 7; minivan.fuelcap = 16; minivan.mpg = 21; sportscar.passengers = 2; sportscar.fuelcap = 14; sportscar.mpg = 12; System.out.print("minivan can carry "+minivan.passengers + " "); minivan.range(); System.out.print("sportcar can carry "+sportscar.passengers + " "); sportscar.range(); } } class Vehicle { int passengers; int fuelcap; int mpg; //display the range void range() { System.out.println("Range is "+(fuelcap * mpg)); } }
输出:
minivan can carry 7 Range is 336 sportcar can carry 2 Range is 168
我们从range()方法开始来看一下该程序的关键元素.range()的第一行代码是:
void range()
这一行声明了一个名为range的无形参方法.他返回的类型是void.因此,range()不向调用者返回值.
range()的主体由下面这行代码组成:
System.out.println("Range is "+(fuelcap * mpg));
该语句显示了fuelcap与mpg相乘得到的汽车行驶里程.因为在调用range()时,Vehicle类型的每个对象都有自己的fuelcap和mpg的副本,所以行驶里程的计算使用了调用对象的这些变量的副本.
下面,我们介绍一下main()中的这行代码:
minivan.range();
该语句调用minivan的range()方法,即他在对象后面使用点运算符,调用与minivan对象相关的range().当调用方法时,程序控制权被转移到方法,当方法结束时,控制权转移回调用者,从调用后的一行代码继续执行.
在range()方法中有一个很重要的细节值得我们注意:没有在实例变量fuelcap和mpg的前面添加对象名或点运算符就直接引用了他们,当一个方法使用由他的类定义的实例变量时,可以直接使用,无须显式引用对象,也无须使用点运算符.思考一下,就会发现这一点是很容易理解的.方法总是被与其相关的对象调用.一旦调用发生,对象就被知晓.因此,在方法中,没有必要第二次指定对象.这就意味着range()中的fuelcap和mpg隐式引用了调用range()的对象中的变量的副本.