类别和协议是Obj-C中比较显著的特性,类别的功能主要是为了实现类的扩展,协议则体现了Obj-C的多态性,经常被用在代理的实现上。
1. 类别
类别其实挺同意理解的,针对的情况就是,比如说我们设计了一个电脑的类叫做myComputer,原有三个方法分别是:startUp、shut down和restart,但后来又觉得不够完善,于是需要加入sleep、login、systemUpdate等,可是现在的情况是,不是只有你一个开发人员在做开发,是整个团队来做,那么这时候我们就可以利用类别来进行扩展。我们来看一段书上的实例:
- #import "myComputer.h"
- @interface myComputer : NSObject
- -(void)startUp;
- -(void)shutDown;
- -(void)restart;
- @end
- @implementation myComputer
- -(void)startup
- {
- NSLog(@"start up my computer");
- }
- -(void)shutDown
- {
- NSLog(@"shut down my computer");
- }
- -(void)restart
- {
- NSLog(@"restart my computer");
- }
- @end
那么这就是我们一开始设计的myComputer类,接下来我们就要在其他的头文件中对他进行扩展,那就必须要引用以前的类的头文件,只有这样儿编译器才能识别myComputer类,后面的小括号里的是类别名:
- #import "myComputer.h"
- @interface myComputer(category1)
- -(void)sleep;
- -(void)login;
- -(void)systemUpdate;
- @end
- @implementation myComputer
- -(void) sleep
- {
- NSLog(@"sleep my computer");
- }
- -(void) login
- {
- NSLog(@"login my computer");
- }
- -(void) systemUpdate
- {
- NSLog(@"system update for my computer");
- }
- @end
- int main(int argc, char *argv[])
- {
- NSAutoreleasePool * pool=[[NSAutoreleasePool alloc] init];
- myComputer *computer=[[myComputer alloc] init];//实例化myComputer对象
- [computer startup]; //调用myComputer类原有的方法
- [computer shutdown];
- [computer restart];
- [computer sleep]; //调用myComputer类扩展的方法
- [computer login];
- [computer systemUpdate];
- [computer release]; //释放computer对象
- [pool drain];
- return 0;
- }
程序的最终输出结果如下:
start up my computer
shut down my computer
restart my computer
sleep my computer
login my computer
system update for my computer
上面的实例演示了如何使用类别来对现有的类进行扩展,但这并不会改变原始的myComputer的构造实现,这点上,类别的功能和继承是有一点相似性的,但是继承可以为子类添加新的成员变量和方法,而类别机制则只能给现有的类添加新的方法而不能添加任何变量。
2. 协议
Obj-C中的协议有些类似C++的纯函数或者java中的interface,协议会定义一系列的方法,每个对象都可以对其进行引用,引用的同时必须实现协议里要求实现的方法,它不同于类和类别,类和类别的接口必须是在实实在在存在的、特定的类里面才得以实现,而协议声明的接口则可以被任何类实现,同时也可以被多个类实现。
(1) 协议的声明
协议声明的语法如下:
@protocol ProtocolName
method declarations
@end
协议的声明以关键字@protocol开头,后面是协议名称,中间是协议方法,最后是结束关键字。协议中方法的属性可以有optional和required两种,required是必须实现的,optional是可选的。
(2)协议的采用
协议采用的语法如下:
@interface ClassName : ItsSuperClass < Protocol List >
在协议的采用中,@interface是关键字,后面是雷鸣,冒号后是父类名,尖括号中是协议名列表,多个协议只见用逗号分隔
(3)协议的实现
采用协议的类必须实现协议要求实现的方法,我们通过书上的一个示例来学习一下:
- //定义协议protocolA
- @protocol protocolA
- -(void)protocolMethod1; //协议中规定的方法
- -(void)protocolMethod2;
- -(void)protocolMethod3;
- -(void)protocolMethod4;
- @end
- @interface myClass:NSObject<protocolA> //遵循协议
- {
- }
- @end
- @implementation myClass //实现协议方法
- -(void) protocolMethod1()
- {
- NSLog(@"implement protocolMethod1");
- }
- -(void) protocolMethod2()
- {
- NSLog(@"implement protocolMethod2");
- }
- -(void) protocolMethod3()
- {
- NSLog(@"implement protocolMethod3");
- }
- -(void) protocolMethod4()
- {
- NSLog(@"implement protocolMethod4");
- }
- @end
(4)协议实现对象委托
委托是面向对象编程中比较经常用到的,在Obj-C中经常用协议来实现对象委托,那么我们就通过示例来实现对象委托:
- //声明协议
- @protocol protocolA
- protocolMethod1; //协议中规定的方法
- protocolMethod2;
- protocolMethod3;
- protocolMethod4;
- @end
- //类myClassA有一个代理变量,它将后面的myClassB设为它的代理,并调用代理的方法
- @interface myClassA : NSObject
- {
- Id_delegate;
- }
- @property(nonatomic, retain) Id_delegate;
- -(void) callDelegateMethod;
- @end
- @implementation myClassA
- @synthesize _delegate;
- -(void)callDelegateMethod
- {
- [_delegate protocolMethod1];
- [_delegate protocolMethod2];
- [_delegate protocolMethod3];
- [_delegate protocolMethod4];
- }
- @end
- //类myClassB采用协议protocolA,并实现协议protocolA定义的方法
- @interface myClassB : NSObject<protocolA>
- {
- }
- -(void)testDelegate;
- @end
- @implementation myClass
- - protocolMethod1()
- {
- NSLog(@"implement protocolMethod1");
- }
- - protocolMethod2()
- {
- NSLog(@"implement protocolMethod2");
- }
- - protocolMethod3()
- {
- NSLog(@"implement protocolMethod3");
- }
- - protocolMethod4()
- {
- NSLog(@"implement protocolMethod4");
- }
- -(void)testDelegate
- {
- //创建myClassA实例
- myClassA *A=[[myClassA alloc] init];
- //设置代理
- _delegate=self;
- [A callDelegateMethod];
- }
- @end
程序最终的输出结果如下:
implement protocolMethod1
implement protocolMethod2
implement protocolMethod3
implement protocolMethod4
OK,这样我们就完成了一个通过使用协议来使用委托编程的模式,定义协议protocolA来规定两个对象之间要遵循的方法,myClassB的实例作为myClassA的委托的时候就避免了可能会有的一场情况。
时候不早了,已经周一了,今天就要开始上班了,晚安,新的一天开始的时候我们先养精蓄锐,准备出发。
2013年04月22日,Eric.Tang 记