昨天爬山耽误了一天,所以上午那篇补上昨天的,现在来开始今天的Obj-C的学习,今天主要就学习下Obj-C中的类别和协议。
类别和协议是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 记