3.4.3 类和实例方法
必须定义各种方法才能使用Fractions。需要能够将分数的值设为特定的值。因为你不能直接访问分数的内部表示(就是,直接访问它的实例变量),因此必须编写方法来设置分子和分母。还要编写一个名为print的方法来显示分数的值。下面是print方法的声明,应该位于接口文件中:
-(void)print;
开头的负号(-)通知Objective-C编译器,该方法是一个实例方法。其他唯一的选择是正号(+),它表示类方法。类方法是对类本身执行某些操作的方法,例如创建类的新实例。这类似于制造厂制造一辆新汽车,在这一点上,汽车就是一个类;而要制造新汽车便是类方法。
实例方法对类的特定实例执行一些操作,例如设置值、检索值和显示值等。在制造出一辆汽车后,引用这个汽车实例时,可能要执行给它加油的操作。这个加油操作是对特定的汽车执行的,因此它类似于实例方法。
返回值
声明新方法时,必须通知Objective-C编译器这个方法是否返回值,如果返回值,那么返回哪种类型的值。将返回类型放入开头的负号或者正号之后的圆括号中,可完成这项工作。因此,声明
-(int)retrieveNumerator;
指定名为retrieveNumerator的实例方法将返回一个整型值。类似地,程序行
-(double)retrieveDoubleValue;
声明了一个返回双精度值的方法(第4章“数据类型和表达式”会介绍有关这个数据类型的更多内容)。
使用Objective-C中的return语句可以从方法中返回一个值,这与前一个程序例子中从main内返回值的方式类似。
如果方法不返回值,可用void类型表明,如下所示:
-(void)print;
这条语句声明了一个名为print的方法,它不返回任何值。在这种情况下,无需在方法结尾执行一条return语句。相反,可以执行一条不带任何指定值的return语句,如下所示:
return;
无需为方法指定返回类型,尽管那样做是一个较好的编程习惯。如果没有指定任何类型,那么id将是默认类型。你将在第9章“多态、动态类型和动态绑定”中学到有关id数据类型的更多内容。基本上,id类型可用来引用任何类型的对象。
方法的参数
代码清单3-2的@interface部分声明了其他两个方法:
-(void)setNumerator:(int)n;
-(void)setDenominator:(int)d;
它们都是不返回值的实例方法。每个方法都有一个整型参数,这是通过参数名前面的(int)指明的。就setNumerator来说,其参数名是n。这个名称可以是任意的,它是用来引用参数的方法名称。因此,setNumerator的声明指定向该方法传递一个名为n的整型参数,而且该方法没有要返回的值。这类似于setDenominator的声明,不同之处是后者的参数名是d。
要注意声明这些方法的语法。每个方法名都以冒号结束,这个冒号通知Objective-C编译器该方法期望看到一个参数。然后,指定参数的类型,并将其放入一对圆括号中,这与为方法自身指定返回类型的方式十分相似。最后,使用象征性的名称来确定方法所指定的参数。整个声明以一个分号结束。这个语法在图3-1中做了描述。
图 3-1 方法的声明
如果方法接受一个参数,那么在引用该方法时在方法名之后附加一个冒号。因此,setNumerator:和setDenominator:是指定这两个方法的正确方式,每个方法都有一个参数。同样,在指定print方法时没有使用后缀的冒号,这表明此方法不带有任何参数。在第7章“类”中,将学习如何指定带有多个参数的方法。