3.3.1 追加新方法的例子 我们来定义一个带有静音功能的类 MuteVolume。该类只有一个功能,即当收到mute消息时, 设置音量为最小。 类 MuteVolume 的定义非常简单,父类是已经定义好的类 Volume。子类 MuteVolume 除了可以使 用父类 Volume 中定义的所有实例变量和方法之外,还新增加了一个 mute 方法。 代码清单 3-1 文件 MuteVolueme.h-版本 1 #import"Volume.h" @interfaceMuteVolume:Volume/*父类是Volume*/ -(id)mute; @end 这里使用了 Volume 作为父类,并引入了头文件 Volume.h。Volume 的父类是 NSObject,所以 , 所以就不需要再进行指定了。 没有定义新的实例变量,意味着子类中没有要追加的实例变量。 代码清单 3-2 文件 MuteVolume.m-版本 1 #import"MuteVolume.h" @implementationMuteVolume -(id)mute { val=min; returnself; } @end 代码清单 3-3 用于测试类 MuteVolume 的 main 程序 #import"MuteVolume.h" #import<stdio.h> intmain(void) { idv; charbuf[8]; v=[[MuteVolumealloc]initWithMin:0max:10step:2]; while(scanf("%s",buf)>0){ switch(buf[0]){ case'u':[vup];break; case'd':[vdown];break; case'm':[vmute];break; case'q':return0; } printf("Volume=%dn",[vvalue]); } return0; } 该测试程序的功能是从终端读入输入的字符串,并根据字符串的第一个字符来决定如何设置音 量。具体来说,第一个字符为 u 时表示提高音量,d 表示降低音量,m 表示静音,q 表示退出程序。 编译子类的时候,需要连同父类一起编译和链接,否则就无法使用父类中定义的方法。本例中 编译所需要的文件一共有 5 个,即 Volume.h、Volume.m、MuteVolume.h、MuteVolume.m、main.m。 %clangmain.mVolume.mMuteVolume.m-frameworkFoundation 3.3.2 方法重写的例子 上面通过继承实现静音功能类的例子非常简单,让我们来看一个更实用的例子。 假设该例子要实现两个功能。第一个功能是,当再次收到mute消息时,音量会恢复原值;第二 个功能是,在静音状态下收到up或down消息时,会返回最小音量值,同时改变音量值。 实现这些功能的方法有很多,这里我们增加一个 BOOL 类型的变量 muting,同时修改方 法initWithMin:max:step:和 方法value的 实现。 代码清单 3-4 文件 MuteVolume.h-版本 2 #import"Volume.h" @interfaceMuteVolume:Volume/*MuteVolume 的父类是Volume*/ { BOOLmuting; } /*override*/ -(id)initWithMin:(int)amax:(int)bstep:(int)s; -(int)value; -(id)mute; @end 代码清单3-5 文件 MuteVolume.m-版本 2 #import"MuteVolume.h" @implementationMuteVolume /*override*/ -(id)initWithMin:(int)amax:(int)bstep:(int)s { self=[superinitWithMin:amax:bstep:s]; if(self!=nil) muting=NO; returnself; } /*override*/ -(int)value { returnmuting?min:val; } -(id)mute { muting=!muting; returnself; } @end 初始化方法initWithMin:max:step:首 先调用了父类的初始化方法,然后对新增的实例变量 muting 进行了初始化。如前所述,子类的初始化一定要在父类的初始化之后进行。 value方 法根据当前是否为静音状态返回不同的值。静音状态下,返回最小值 min。mute方法 中只需要改变实例变量 muting 的状态来标识是否静音,不需要更改音量值 val。 编译的情况和上一节一样。main.m 直接使用上一节的即可。