转自:http://blog.csdn.net/littlecat0_0/article/details/8592323
问题:Object-C有多继承吗?没有的话用什么代替?Category是什么?重写一个类的方式用继承好还是分类好?为什么?
OC没有多继承,例如下面的代码,肯定必须报错的。
其实OC也有类似java的多继承,就是委托delegate和协议protocol。
protocal协议机制是一种类似java的接口的玩意。定义一组方法,但是不实现,让使用它的类去做实现。任何一个使用它的类只要声明了该协议,都可以实现协议中的方法。
portoco通常和delegate一起使用。delegate委托不是什么机制,只是一种设计模式。
下面举个例子说明。某个同学需要买一本书,所以他就声明了一个叫buybook的协议。但是这个协议由谁来实现呢,他并不关心。然后卖书的商家发现自己有这本书,就实现这个方法。
首先我们看Student的.h和.m文件的实现
- <span style="font-size:14px;">#import <Foundation/Foundation.h>
- //协议在后面定义,先在前面声明
- @protocol MyDelegate;
- @interface Student : NSObject
- @property(nonatomic,retain)id<MyDelegate> s_delegate;
- -(void)wantBuy;
- @end
- //定义协议
- @protocol MyDelegate<NSObject>
- -(void)buyBook:(NSString *)name price:(int)p;
- @end</span>
- #import "Student.h"
- @implementation Student
- -(void)wantBuy {
- NSLog(@"我想买IOS开发的书");
- [self.s_delegate buyBook:@"IOS开发" price:50];
- }
- @end
然后我们只要在viewcontroller的viewDidLoad方法中调用一下代码
- Student *stu =[[[Student alloc]init]autorelease];
- [stu wantBuy];
可见,我想买书的消息(协议已经发出了,可是,由谁来实现这个委托呢?)我们在做一个bookShop的类
.h
- <span style="font-size:14px;">#import <Foundation/Foundation.h>
- #import "Student.h"
- @interface BookShop : NSObject<MyDelegate>
- @end</span>
- #import "BookShop.h"
- @implementation BookShop
- //商家实现协议的方法
- -(void)buyBook:(NSString *)name price:(int)p {
- NSLog(@"我可以以%i元的价格把%@卖个你",p,name);
- }
- @end
- Student *stu =[[[Student alloc]init]autorelease];
- BookShop *bs = [[[BookShop alloc]init]autorelease];
- stu.s_delegate=bs;
- [stu wantBuy];
这就是委托跟代理的关系了。其实很多时候,我们的委托的对象是我们自己,即
- stu.s_delegate=self;
下面继续Category分类。
Category的作用是动态为已存在的类添加新的行为。使用Categroy对类进行扩展的时候不需要访问其源码,也不需要创建子类。
例如我们为上面的学生类创建一个关于play的分类。
首先new File中选择Cocoa Touch下的Objective-C category
然后注意的是Category on里面的要写Student,就是你要为之扩展分类的类。
next之后你会发现左边的目录栏上多了下面两个文件
然后我为Student+Play的两个文件添加方法
- #import "Student.h"
- @interface Student (Play)
- -(void)Singing;
- -(void)dance;
- @end
- #import "Student+Play.h"
- @implementation Student (Play)
- -(void)Singing {
- NSLog(@"I can singing");
- }
- -(void)dance {
- NSLog(@"I can dance");
- }
- @end
- Student *stu =[[[Student alloc]init]autorelease];
- [stu dance];
- Student *stu =[[[Student alloc]init]autorelease];
- [stu dance];
Categroy应用到的地方一般有:
A.一个类之中包含很多个或很多种类别的方法,需要由不同的团队成员去完成。
B.当你觉得基础类库中的某些类不能满足你的需求时,可以为其添加分类。如为NSString添加JSON分类。
categroy可以重载原始类的方法,它会覆盖掉原始类的方法,所以一般不建议使用。