OutMan——Objective-C中分类、延展、非正式协议和协议
来源:互联网 发布:csgo控制台优化 编辑:程序博客网 时间:2024/05/22 07:02
分类(category:分类、类别、类目)
一、分类的作用
分类的作用是:在不改变原来类的基础上,可以增加一些方法
二、分类的使用注意
1. 分类只能增加方法,不能增加成员变量(也不能使用@property生成原来类中没有的成员变量)
2. 分类方法实现中可以访问原来类中声明的成员变量
3. 分类可以重新实现原来类中的方法,但会覆盖掉原来的方法,会导致原来的方法没法再使用
4. 方法调用的优先级:分类(最后参与编译的分类优先)—>原来类—>父类
5. 分类增加的方法能被子类继承
三、如何给某个类分类
四、使用分类的目的
1. 对现有的类进行扩展:比如你可以扩展Cocoa touch框架中的类,你在分类中增加的方法会被子类继承,而且在运行时跟其他方法没有区别
2. 作为子类的代替手段:不需要定义和使用一个子类,可以通过分类直接向已有的类里增加方法
3. 对类中的方法归类:利用分类把一个庞大的类划分为多个小块来分别进行开发,从而更好的对类中方法进行更新和维护
五、分类的代码分析
(1)Person类的设计
Person.h文件
#import <Foundation/Foundation.h>@interface Person : NSObject{ int _age;}@property int age; // 年龄// run方法的声明- (void)run;// test方法的声明- (void)test;@end
Person.m文件
#import "Person.h"@implementation Person// run方法的实现- (void)run{ NSLog(@"%d岁的人在奔跑", _age);}// test方法的实现- (void)test{ NSLog(@"Person----->test");}@end
(2)Person类的分类Person+Eat类的设计
Person+Eat.h文件
#import "Person.h"@interface Person (Eat)// eat方法的声明- (void)eat;@end
Person+Eat.m文件
#import "Person+Eat.h"@implementation Person (Eat)// eat方法的实现- (void)eat{ NSLog(@"%d岁的人在吃东西", _age);}// test方法的实现- (void)test{ NSLog(@"Person+Eat----->test");}@end
(3)Person类的分类Person+Jump类的设计
Person+Jump.h文件
#import "Person.h"@interface Person (Jump)// jump方法的声明- (void)jump;@end
Person+Jump.m文件
#import "Person+Jump.h"@implementation Person (Jump)// jump方法的实现- (void)jump{ NSLog(@"%d岁的人在跳", _age);}// test方法的实现- (void)test{ NSLog(@"Person+Jump----->test");}@end
(4)main.m文件
-设计注意:
1. 分类可以重新实现原来类中的方法,但会覆盖掉原来的方法,会导致原来的方法没法再使用
2. 当调用[p test]的时候,为什么打印的是Person+Eat—–>test?
方法调用的优先级:分类(最后参与编译的分类优先)—>原来类—>父类
3. 如何查看编译顺序
从图中可以看出,最后参与编译的分类是Person+Eat这个分类,所以当调用[p test]的时候,打印的是Person+Eat—–>test
延展(扩展、延展类别)
一、延展的概念
延展类别称为扩展(Extension)又称为延展,延展(Extension)是分类(category)的一个特例,其名字为匿名(为空),并且新添加的方法一定要予以实现(分类则没有这个限制)
延展其实就是特殊的分类,这种写法的分类也叫匿名分类,所谓的延展,其实就是为一个类添加额外的原来没有的变量、方法或合成属性
二、延展的特点
1. 可以在延展中定义成员变量
2. 不能使用@implementation 类名()实现延展的方法
3. 可以在延展中定义私有的成员变量和方法
三、如何给某个类延展
四、延展和分类的区别
1. 分类中只能增加方法
2. 延展中不仅可以增加方法,还可以增加成员变量(或者合成属性),只是该变量默认是私有类型的(作用范围只能在自身类,而不是子类或其他地方)
3. 延展中声明的方法没有被实现,编译器会报警告,但是分类中的方法没有被实现,编译器是不会有任何警告的,这是因为延展是在编译阶段被添加到类中,而分类实在运行时添加到类中
4. 延展不能像分类那样,拥有独立的实现部分(@implementation部分),也就是说,类扩展所声明的方法必须依托对应类的实现部分来实现
5. 定义在.m文件中的延展方法为私有的,定义在.h文件中的延展方法为公有的,延展是在.m文件中声明私有方法的非常好的方式
五、延展的代码实现
(1)Person类的设计
Person.h文件
#import <Foundation/Foundation.h>@interface Person : NSObject@property int age; // 年龄// run方法的声明- (void)run;@end
Person.m文件
#import "Person.h"#import "Person_Eat.h"@implementation Person// run方法的实现- (void)run{ NSLog(@"%d岁的人在奔跑", _age);}// eat方法的实现- (void)eat{ NSLog(@"名字是%@,%d岁的正在吃", _name, _age);}@end
(2)Person类的延展Person_Eat类的实现
Person+Eat.h文件
#import "Person.h"@interface Person ()@property NSString *name; // 姓名// eat方法的声明- (void)eat;@end
(3)main.m文件
-设计注意:
1. 延展中不仅可以增加方法,也可以增加成员变量或者合成属性),只是该变量默认是私有类型的(作用范围只能在自身类,而不是子类或其他地方)
非正式协议
一、非正式协议概念
所谓的非正式协议:凡是NSObject的分类或其子类Foundation框架中的类的分类,都是非正式协议
二、非正式协议的实现代码:
设计要求:给NSString增加一个类方法,计算某个字符串中阿拉伯数字的个数,给NSString增加一个对象方法,计算某个字符串中阿拉伯数字的个数
(1)非正式协议的设计
NSString+CountNumber.h文件
#import <Foundation/Foundation.h>@interface NSString (CountNumber)// 计算字符串中数字个数方法的声明+ (int)countNumber:(NSString *)aString;// 计算字符串中数字个数方法的声明- (int)countNumber;@end
NSString+CountNumber.m文件
#import "NSString+CountNumber.h"@implementation NSString (CountNumber)// 计算字符串中阿拉伯数字个数方法的实现+ (int)countNumber:(NSString *)aString{ int count = 0; for(int i=0; i<aString.length; i++) { // 取出字符串中对应index位置的字符 unichar c = [aString characterAtIndex:i]; // 如果这个字符是阿拉伯数字 if (c>='0' && c<='9') { count++; } } return count;}// 计算字符串中阿拉伯数字个数方法的实现- (int)countNumber{ int count = 0; for(int i=0; i<self.length; i++) { // 取出字符串中对应index位置的字符 unichar c = [self characterAtIndex:i]; // 如果这个字符是阿拉伯数字 if (c>='0' && c<='9') { count++; } } return count;}@end
(2)main.m文件
-设计注意:
1. for循环中,通过length方法来获取字符串的长度
2. 通过调用字符串的对象方法来获取对应index位置的字符,然后再进行判断当前字符是否是阿拉伯数字
3. if (c>=’0’ && c<=’9’)中‘0’和‘9’必须要加单引号,不加单引号是ASCII码值0和9,而不是字符0和9
协议
一、基本用途
1. 可以用来声明一大堆方法(不能声明成员变量)
2. 只要某个类遵守了这个协议,就相当于拥有了这个协议中所有的方法声明
3. 只要父类遵守了某个协议,就相当于子类也遵守了
二、格式
(1)协议的编写
@protocol 协议名称
// 方法列表
@end
(2)某个类遵守协议
@interface 类名:父类<协议名称>
@end
三、如何创建协议
四、协议中的关键字
协议中有2个关键字可以控制方法是否要实现(默认是@required),在大多数情况下,用途在于程序员之间的交流
@required:这个方法必须要实现(若不实现,编译器会发出警告)
@optional:这个方法不一定要实现
五、协议之间的遵守、基协议
(1)协议遵守协议
1. 一个协议可以遵守其他多个协议,多个协议之间用逗号隔开
2. 一个协议遵守了其他协议,就相当于拥有了其他协议中的方法声明
3. 格式:
@protocol 协议名称<协议1,协议2…>
@end
(2)基协议
1. NSObject是一个基类,最根本的类,任何其他类都最终要继承它
2. 其实还有个协议,名字也叫NSObject,它是一个基协议,最根本最基本的协议
3. NSObject协议中声明了很多最基本的方法,比如description、retain、release等
4. 建议每个新的协议都要遵守NSObject协议
六、Protocol限制对象类型
(1)要求obj保存的对象必须是遵守MyProtocol这个协议
NSObject<MyProtocol> *obj = [[Person alloc] init];
(2)要求obj保存的对象必须遵守MyProtocol协议并且继承了Person类
Person<MyProtocol> *obj = [[Person alloc] init];
七、协议的提前声明
1. @protocol 协议名称;提前声明
2. 当使用到这个协议里面的东西的时候,再#import这个协议的头文件
3. 在mian.m文件中调用协议中的方法时,也需要#import这个协议的头文件
八、协议的代码实现
(1)RunProtocol协议的设计
RunProtocol.h文件
#import <Foundation/Foundation.h>@protocol RunProtocol <NSObject>// run方法的声明- (void)run;@end
-设计注意:
1. 协议中的方法声明默认是@required(需要实现的)
(2)JumpAndSingProtocol协议的设计
JumpAndSingProtocol.h文件
#import <Foundation/Foundation.h>@protocol JumpAndSingProtocol <NSObject>@required// jump方法的声明- (void)jump;@optional// sing方法的声明- (void)sing;@end
-设计注意:
1. @required:这个方法必须要实现(若不实现,编译器会发出警告)
2. @optional:这个方法不一定要实现
(3)EatProtocol协议的设计
EatProtocol.h文件
#import <Foundation/Foundation.h>#import "JumpAndSingProtocol.h"#import "RunProtocol.h"@protocol EatProtocol <NSObject, JumpAndSingProtocol, RunProtocol>// eat方法的声明- (void)eat;@end
-设计注意:
1. 一个协议可以遵守其他多个协议,多个协议之间用逗号隔开
2. 一个协议遵守了其他协议,就相当于拥有了其他协议中的方法声明
3. 格式:
@protocol 协议名称<协议1,协议2…>
@end
(4)Person类的设计
Person.h文件
#import <Foundation/Foundation.h>#import "EatProtocol.h"@interface Person : NSObject<EatProtocol>@end
Person.m文件
#import "Person.h"@implementation Person// eat方法的实现- (void)eat{ NSLog(@"Person在吃");}// jump方法的实现- (void)jump{ NSLog(@"Person在跳");}// run方法的实现- (void)run{ NSLog(@"Person在跑");}@end
-设计注意:
1. @required:这个方法必须要实现(若不实现,编译器会发出警告)
2. @optional:这个方法不一定要实现(例:sing方法不实现也没有关系)
(5)main.m文件
—— 如果您有不同的见解,请随时指出,期待与您的交流!——
- OutMan——Objective-C中分类、延展、非正式协议和协议
- Objective-C 【Category-非正式协议-延展】
- Objective-c - 非正式协议
- 黑马程序员——OC基础---分类(Category)、非正式协议及分类延展
- Objective-C中的类别和非正式协议
- Objective-C中的类别和非正式协议
- Objective-C基础—分类和协议
- Objective-C 的正式协议和非正式协议
- objective-C中的"非正式协议"和“正式协议”
- Objective-C非正式协议与正式协议
- Objective-C非正式协议与正式协议
- Objective-C非正式协议与正式协议
- Objective-C 委托、非正式协议、正式协议
- Objective-C非正式协议与正式协议
- Objective-C非正式协议与正式协议
- objective c 类目 延展 协议
- Objective-c:类目、延展、协议
- objective-c延展类目协议
- http: 支持 Content-Encoding: gzip
- ARM裸机程序研究 - 编译和链接
- linux中文件描述符fd和文件指针flip的理解
- POJ 1836 Alignment(DP LIS)
- noip2001 求先序排列 (已知中序+后序,求解先序 ;分治)
- OutMan——Objective-C中分类、延展、非正式协议和协议
- python_学习笔记0824
- Linux 下的shell快捷键
- cookie 和session 的区别
- Linux系统内存管理及相关操作函数
- 创业团队新产品开发模式----寻找一个可持续升级、重复、盈利的模式
- HDU 5400(Arithmetic Sequence-暴力找区间)
- hdu5273(区间DP)
- I love sneakers!(分组背包HDU3033)