首页 技术 正文
技术 2022年11月18日
0 收藏 783 点赞 3,925 浏览 5080 个字

篇文章里我们来聊聊如何扩展一个类的方法和实例变量,我们首先来看一下命名分类如何扩展一个类。在下面的代码中,首先定义一个类Player用来定义普通球员,如果第三方开发者发现普通球员缺少了一些方法,则可以用分类ext来扩充喽:

:默认的Player类

Player.h文件:

#import<Foundation/Foundation.h>@interfacePlayer:NSObject{intnumber;intage;}-(void)show;-(id)init:(int)n:(int)age;@end

Player.m文件:

#import"Player.h"@implementationPlayer-(id)init:(int)n:(int)age_v{self= [super init];if(self){number= n;age= age_v;}returnself;}-(void)show{NSLog(@"playerx ,number:%d,age:%d",number,age);}@end

test.m文件:

#import"Player.h"intmain(int argc,char **argv){@autoreleasepool{Player*p = [[Player alloc] init: 1 :20];[pshow];}return0;}

编译执行结果如下:

apple@kissAir:Player$clang -fobjc-arc -framework Foundation
Player.m test.m -o main

apple@kissAir:Player$./main

2014-06-3017:55:56.053 main[3862:507] player
x ,number:1,age:20

现在一个第三方软件公司觉得球员球员太不活泼,so他们决定给球员添加方法say和train:

Player_ext.h文件

#import"Player.h"@interfacePlayer (ext)//@propertyint power;//-(id)init:(int)n:(int)age :(int)power;-(void)say;-(void)train;@end

Player_ext.m文件

#import"Player_ext.h"@implementationPlayer (ext)//@synthesizepower;/*-(id)init:(int)n :(int)age_v :(int)pow{self= [super init :n :age_v];if(self){power= pow;}returnself;}*/-(void)say{NSLog(@"player[n:%d]want to say : hello!",number);}-(void)train{NSLog(@"player[n:%d]is training...",number);}@end

test.m文件

//#import"Player.h"#import"Player_ext.h"intmain(int argc,char **argv){@autoreleasepool{Player*p = [[Player alloc] init: 1 :20];[pshow];[psay];[ptrain];}return0;}

我们编译运行看看结果咯:

apple@kissAir:Player$clang -fobjc-arc -framework Foundation
Player.m Player_ext.mtest.m -o main

apple@kissAir:Player$./main

2014-06-3018:16:09.050 main[4246:507] player
x ,number:1,age:20

2014-06-3018:16:09.052 main[4246:507] player[n:1]
want to say : hello!

2014-06-3018:16:09.053 main[4246:507] player[n:1]
is training…

我们发现在命名分类中试图添加实例变量是不允许的,只能在未命名分类中添加,而且未命名分类中声明方法的实现只能放在主类的实现中。下面修改代码,增加power属性,并且train动作是要耗费power的,遂修改该方法,同时新增init方法如下:

@implementation Player (ext)//@synthesize power;/*-(id)init :(int)n :(int)age_v :(int)pow{self = [super init :n :age_v];if(self){power = pow;}return self;}*/-(void)say{NSLog(@"player[n:%d] want to say : hello!",number);}-(void)train{NSLog(@"player[n:%d:pow:%d] is training...power is down to %d",\number,self.power,self.power -= 10);}

Player.h文件

#import <Foundation/Foundation.h>@interface Player:NSObject{int number;int age;}-(void)show;-(id)init:(int)n :(int)age;@end@interface Player ()@property int power;-(id)init :(int)n :(int)age :(int)power;@end

Player.m文件

#import "Player.h"@implementation Player@synthesize power;-(id)init:(int)n :(int)age_v{self = [super init];if(self){number = n;age = age_v;}return self;}-(id)init :(int)n :(int)age_v :(int)pow{self = [super init];if(self){self = [self init :n :age_v];power = pow;}return self;}-(void)show{NSLog(@"player x ,number:%d,age:%d,power:%d",number,age,power);}@end

test.m文件

#import "Player_ext.h"int main(int argc,char **argv){@autoreleasepool{Player *p = [[Player alloc] init: 1 :20 :100];[p show];[p say];[p train];[p show];}return 0;}

编译运行结果如下:

apple@kissAir: Player$clang -fobjc-arc -framework Foundation Player.m Player_ext.m test.m -o main

apple@kissAir: Player$./main

2014-06-30 18:52:29.237 main[4822:507] player x ,number:1,age:20,power:100

2014-06-30 18:52:29.239 main[4822:507] player[n:1] want to say : hello!

2014-06-30 18:52:29.240 main[4822:507] player[n:1:pow:100] is training…power is down to 90

2014-06-30 18:52:29.240 main[4822:507] player x ,number:1,age:20,power:90

有球员就有教练啊,现在添加教练类。教练类和球员类有共性的地方哦,就是都有say和train方法。这个共性的地方不妨就用协议来描述吧,需要说明的是教练还有一个召开发布会方法,该方法球员是没有的,我们把它作为一个可选方法放入协议。为了方便就把教练类放在test.m中喽:

Player.h文件

#import <Foundation/Foundation.h>@protocol Actions-(void)say;//必须存在@optional-(void)convoke;  //可选方法@required-(void)train; //必须存在@end@interface Player:NSObject{int number;int age;}-(void)show;-(id)init:(int)n :(int)age;@end@interface Player ()@property int power;-(id)init :(int)n :(int)age :(int)power;@end

Player_ext.h文件

#import "Player.h"@interface Player (ext) <Actions>//@property int power;//-(id)init:(int)n :(int)age :(int)power;-(void)say;-(void)train;@end

test.m文件

//#import "Player.h"#import "Player_ext.h"@interface Coach:NSObject <Actions>@end@implementation Coach-(void)say{NSLog(@"coach say : hello!");}-(void)train{NSLog(@"coach is leading train...");}-(void)convoke{NSLog(@"coach is convoking a meeting...");}@endint main(int argc,char **argv){@autoreleasepool{Player *p = [[Player alloc] init: 1 :20 :100];Coach *c = [[Coach alloc] init];[p show];[c say];[c convoke];[c train];[p say];[p train];[p show];}return 0;}

编译运行结果如下:

apple@kissAir: Player$./main

2014-06-30 20:33:24.930 main[6466:507] player x ,number:1,age:20,power:100

2014-06-30 20:33:24.932 main[6466:507] coach say : hello!

2014-06-30 20:33:24.933 main[6466:507] coach is convoking a meeting…

2014-06-30 20:33:24.933 main[6466:507] coach is leading train…

2014-06-30 20:33:24.934 main[6466:507] player[n:1] want to say : hello!

2014-06-30 20:33:24.934 main[6466:507] player[n:1:pow:100] is training…power is down to 90

2014-06-30 20:33:24.934 main[6466:507] player x ,number:1,age:20,power:90

如果要添加多个协议语法为: @interface A <p_a,p_b>

最后我们可以用反射方法测试类是否遵守协议:

Protocol *actions = @protocol(Actions);Player *p = [[Player alloc] init: 1 :20 :100];Coach *c = [[Coach alloc] init];if([p conformsToProtocol: actions]){NSLog(@"Player abide protocol Actions"); //Coach同样遵守}//对于可选方法我们可以用一般的respondsToSelector方法来测试:if([c respondsToSelector :@selector(convoke)]){NSLog(@"Coach has convoke method");}
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,037
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,522
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,370
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,151
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,784
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,866