iOS开发之Objective C编程中的类别
2015-07-02 19:17
387 查看
在 OC编程里面我们可以自已定义我们需要的类,然后根据实际的需要在该类中添加属性,以及一些需要的方法。但是还有一些类我们是不能通过建立其子类的方式来添加属性和方法的,这种类叫作类簇,例如NSString,NSArray等类。
类簇(也叫类族)实际上里面包含了好几种子类在里面,通过这样我们可以隐藏“抽象基类”的实现细节。例如,在ios的用户界面框架UIKit中有个名为UIButton的类,故名思义是一个关于按钮的类,当我们要创建按钮的时候应该调用一个下面这个类方法:
+(UIButton*)buttonWithTyoe:(UIButton)type;
在该方法返回的对象,其类型取决于传入的按钮类型,然而不管是什么类型都是继承自基类:UIButton,所以你在创建的按钮的时候不用管到底是属于哪个子类。也不用管按钮的绘制方式等细节时如何实现的,你只需要输入类型则改方法就会返回你想要的类型。
所以创建一个NSString对象:NSString *string 则会根据你传入的格式来返回对象。所以这种类簇形式的类是不好建立其子类来扩展其属性和方法的。但是有一种手段叫做类别是专门来解决这个问题的。
下面以NSString 为例创建一个类别:
@interface NSString (NumberConvenience)
-(NSNumber*)lengthASNbumber;
@end
NSString 是你为需要添加方法的的类簇的类名
NumberConvenience 是类别名字
然后是你需要添加的方法名称。
类别也是相当于继承了类簇的所有属性,因此在实现添加的方法中可以访问实例变量以及属性,但是类别有个明显的缺点就是不能为类簇添加实例变量,但是可以添加属性,由于在编译过程中属性会产生实例变量,因此属性需要声明为@dynamic 类型的(即不生成实例变量以及获取方法)。
类别还有两个重要的作用:
1、可以将一个类的所有方法分开在不同的文件里面实现,充分体现了代码的模块化思想。
例如在一个类Thing 的头文件里面声明了很多个方法:
-(void)thing1;
-(void)thing2;
-(void)thing3;
-(void)thing4;
............
如果不分散实现的话,那么在其对应的.m实现文件里面就会出现很长的代码,这样很不清晰实现文件的功能,
现在我们在头文件中用类别来声明这些相应模块的函数:
@interface Thing (thing1)
-(void)thing1;
@end
.
.
.
.
这样我们可以在不同的实现文件里面去写相应的代码,这样写出的代码比较短小而且清晰。
2、通过类别来创建前向引用
例如当在一个实现文件里面的某个函数test1里面调用了另外一个函数test2,然而test2函数是定义在test1后面的,那么编译器就会发出前向警告。解决该问题的方法有两个。
第一是在相应的头文件里面声明test2,然后包含头文件。
第二是在test2对应的实现文件里的开始添加类别声明test2
@interface thing(test)
-(void)test2
@end
通过类别我们可以为类簇这种不好创建子类的类来添加方法。但是类别有个明显的缺点就是不能为类簇添加实例变量,因此为解决这个问题,又有了一种技术叫做类扩展。
类扩展:就是在和前面创建类别一样,只是不需要类别名了。
@interface NSStrig ()
{
NSInteger thing;
}
@end
同时,类扩展还可以修改对应的类的属性的特质
例如:在类名为Thing 的类里面有个属性
@property (readonly) NSString *string
该属性声明为只读,则只能读里面的内容而不能修改,但是,我们想对外来说是只能读不能写的,而我们自己是可以读写的,那怎么办呢?
现在通过类扩展可以修改其特质
@property (writeread)NSString *string
这样属性string我们便可对其读写操作,而对外的头文件中仍然只是可读的。
希望读者好好体会,如有疑问,请邮件:auto_zch_wang@163.com
类簇(也叫类族)实际上里面包含了好几种子类在里面,通过这样我们可以隐藏“抽象基类”的实现细节。例如,在ios的用户界面框架UIKit中有个名为UIButton的类,故名思义是一个关于按钮的类,当我们要创建按钮的时候应该调用一个下面这个类方法:
+(UIButton*)buttonWithTyoe:(UIButton)type;
在该方法返回的对象,其类型取决于传入的按钮类型,然而不管是什么类型都是继承自基类:UIButton,所以你在创建的按钮的时候不用管到底是属于哪个子类。也不用管按钮的绘制方式等细节时如何实现的,你只需要输入类型则改方法就会返回你想要的类型。
所以创建一个NSString对象:NSString *string 则会根据你传入的格式来返回对象。所以这种类簇形式的类是不好建立其子类来扩展其属性和方法的。但是有一种手段叫做类别是专门来解决这个问题的。
下面以NSString 为例创建一个类别:
@interface NSString (NumberConvenience)
-(NSNumber*)lengthASNbumber;
@end
NSString 是你为需要添加方法的的类簇的类名
NumberConvenience 是类别名字
然后是你需要添加的方法名称。
类别也是相当于继承了类簇的所有属性,因此在实现添加的方法中可以访问实例变量以及属性,但是类别有个明显的缺点就是不能为类簇添加实例变量,但是可以添加属性,由于在编译过程中属性会产生实例变量,因此属性需要声明为@dynamic 类型的(即不生成实例变量以及获取方法)。
类别还有两个重要的作用:
1、可以将一个类的所有方法分开在不同的文件里面实现,充分体现了代码的模块化思想。
例如在一个类Thing 的头文件里面声明了很多个方法:
-(void)thing1;
-(void)thing2;
-(void)thing3;
-(void)thing4;
............
如果不分散实现的话,那么在其对应的.m实现文件里面就会出现很长的代码,这样很不清晰实现文件的功能,
现在我们在头文件中用类别来声明这些相应模块的函数:
@interface Thing (thing1)
-(void)thing1;
@end
.
.
.
.
这样我们可以在不同的实现文件里面去写相应的代码,这样写出的代码比较短小而且清晰。
2、通过类别来创建前向引用
例如当在一个实现文件里面的某个函数test1里面调用了另外一个函数test2,然而test2函数是定义在test1后面的,那么编译器就会发出前向警告。解决该问题的方法有两个。
第一是在相应的头文件里面声明test2,然后包含头文件。
第二是在test2对应的实现文件里的开始添加类别声明test2
@interface thing(test)
-(void)test2
@end
通过类别我们可以为类簇这种不好创建子类的类来添加方法。但是类别有个明显的缺点就是不能为类簇添加实例变量,因此为解决这个问题,又有了一种技术叫做类扩展。
类扩展:就是在和前面创建类别一样,只是不需要类别名了。
@interface NSStrig ()
{
NSInteger thing;
}
@end
同时,类扩展还可以修改对应的类的属性的特质
例如:在类名为Thing 的类里面有个属性
@property (readonly) NSString *string
该属性声明为只读,则只能读里面的内容而不能修改,但是,我们想对外来说是只能读不能写的,而我们自己是可以读写的,那怎么办呢?
现在通过类扩展可以修改其特质
@property (writeread)NSString *string
这样属性string我们便可对其读写操作,而对外的头文件中仍然只是可读的。
希望读者好好体会,如有疑问,请邮件:auto_zch_wang@163.com
相关文章推荐
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 不可修补的 iOS 漏洞可能导致 iPhone 4s 到 iPhone X 永久越狱
- iOS 12.4 系统遭黑客破解,漏洞危及数百万用户
- 每日安全资讯:NSO,一家专业入侵 iPhone 的神秘公司
- [转][源代码]Comex公布JailbreakMe 3.0源代码
- Linux C函数参考手册(PDF版)
- 杰奇分类设置方法
- Lua教程(十七):C API简介
- C#实现打造气泡屏幕保护效果
- C/C++数据对齐详细解析
- C 语言基础教程(我的C之旅开始了)[三]
- C++中的extern “C”用法详解
- C 语言基础教程(我的C之旅开始了)[七]
- C字符串操作函数实现方法小结
- C/C++ 宏详细解析
- C/C++实现对STORM运行信息查看及控制的方法
- 用C#生成不重复的随机数的代码