黑马程序员——OC的Category和Protocol

———-android培训、Java培训、iOS培训,期待与您交流———-

Category

一、基本概念

  1. 分类的作用:

    • 在不修改原有的类的基础上增加新的方法
    • 一个庞大的类可以分模块开发,便于维护
    • 一个庞大的类可以由多个人来编写,更有利于团队合作
  2. 使用类别的目的

    • 对现有类进行扩展:对自定义的类甚至是框架中的类进行扩展,从而实现项目特殊需求。
    • 作为子类的替代手段:不需要定义和使用一个子类,可以通过类别直接向已有的类中增加方法。
    • 对类中的方法归类:利用category把一个庞大的类划分为小块来分别进行开发,从而更好的对类中的方法进行更新和维护。
  3. 关于非正式协议

    为NSObject添加的分类就称作非正式协议。非正式协议一般不需要进行实现,而是在子类中进行方法的重写。

二、分类的使用

1.分类的实现步骤
  1. 声明

    格式:

    @interface 待扩展的类名 (分类的名称)

    @end

  2. 实现

    格式:

    @implementation 待扩展的类名 (分类的名称)

    @end

  3. 文件的命名格式:

    待扩展的类名+分类名称

  4. 使用

    与使用类中原有的方法一样,用方括号调用。

2.代码举例

假设现在已经有Person类,要创建一个Person的类扩展,首先在当前target中新建Objective-C File,文件名填写分类名称,File Type选择Category,类名填写要扩展的类名。文件创建好之后,就像使用普通类一样,在.h文件中声明方法,在.m文件中实现方法。例如:

/******Person+play.h*******/
#import "Person.h"

@interface Person (play)
-(void)paly;
@end
/******Person+play.m*******/
#import "Person+play.h"

@implementation Person (play)
-(void)paly{
    NSLog(@"playing");
}
@end

这样在使用Personm类时就可以直接调用play方法了。

但是Category也有他的局限:

  • 不能在Category中扩展类的成员变量
  • 名称冲突,当Category中实现的类与已有方法重名时,会完全取代已有方法。

三、类扩展(延展)

1.类扩展的作用

分类(Category)的一个缺陷是只能扩展方法而不能扩展成员变量,类扩展(Class Extension)可以实现向原有类中添加成员变量。

2.实现方法

类扩展实际上是一个特殊的分类,在定义@interface的时候不对分类进行命名,这个分类就成了一个类扩展。创建类扩展的时候在新建文件时File Type选择Extension即可。例如:

/******Person_body.h*******/
#import "Person.h"

@interface Person ()
{
    float _weight;
    float _height;
}
@end

3.注意

  • 类扩展只有@interface部分而没有@implementation
  • 类扩展也可以添加方法,但是方法的实现要写在类的.m文件中
  • 可以改变变量的读写权限

Protocol

一、基本概念

1.Protocol的作用

Protocol(协议)是包含了方法和属性的有名称列表。采用协议的类必须实现协议要求实现的方法,否则编译器会报错。

2.协议的使用流程
  1. 定义协议(在.h文件中)

    在当前target中新建Objective-C文件,File Type选择Protocol。

    格式:

    @protocol 协议名称 <NSObject>  //默认遵守NSObject协议
    //方法声明列表 
    @end;
  2. 采用(遵守)协议

    • 类遵守协议

      创建类的时候遵守某个或者某几个协议

    @interface 类名 : 父类 <协议名称1,协议名称2>
    @end
    • 协议遵守协议

      协议也可以遵守一个或多个其他协议

    @protocol 协议名称 <其他协议名称1,其他协议名称2>
    @end
  3. 实现协议要求实现的方法

3.协议的注意事项
  • Protocol:就一个用途,用来声明方法(不能声明成员变量),不能写实现。
  • 只要某个类遵守了这个协议,就拥有了这个协议中的所有方法声明。
  • 只要父类遵守了某个协议,那么子类也遵守。
  • Protocol声明的方法可以让任何类去实现
  • OC不能继承多个类(单继承)但是能够遵守多个协议。
  • 基协议:\
4.可选和必须

在协议中,可以定义一个方法的声明是否必须被实现,通过关键字@optional和@required实现,例如:

@protocol 协议名称 <NSObject> 
@optional
-(void)run;//可选实现,不是必须的
@required
-(void)eat;//必须实现
@end;

默认是@required。

5.类型限制

当创建一个对象时,希望这个对象必须遵守了指定的协议,就需要使用类型限制。

  • 对象赋值时的类型限制

    格式:类名<协议名称> *变量名

    例如:Person<run> *p = [Person new];//只有Person类确实遵守了run协议编译器才不会报错

  • 关联关系下的类型限制

    使用@property声明成员变量时,如果成员变量是一个对象,则可以使用类型限制对对象进行限制,格式如下:@property 类名<协议名> *变量名;

    例如:@property Pet<dog> *pet;//只有遵守了dog协议的Pet类才能作为该类的成员变量

  • 使用id存储对象时的类型限制

    格式:id <协议名称> 变量名

    例如:id<run> p = [Person new]

二、代码实现

/******studyProtocol.h******/
@protocol studyProtocol <NSObject>
-(void)studyOC;
@end
/******playProtocol.h******/
@protocol playProtocol <NSObject>
-(void)playPCgame;
@optional
-(void)playBasket;
@end
/******Person.h******/
#import <Foundation/Foundation.h>
#import "playProtocol.h"
@interface Person : NSObject<playProtocol>
@end
/******Person.m******/
#import "Person.h"

@implementation Person
-(void)playPCgame{
    NSLog(@"Playing PC game now");
}
@end
/******Student.h******/
#import "Person.h"
#import "studyProtocol.h"
@interface Student : Person<studyProtocol>
@end
/******Student.m******/
#import "Student.h"

@implementation Student
-(void)studyOC{
    NSLog(@"Studying OC now");
}
@end
/******main.m******/
#import <Foundation/Foundation.h>
#import "Person.h"
#import "Student.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Person<playProtocol> *p = [Person new];
        [p playPCgame];//->Playing PC game now
        Student *stu = [Student new];
        [stu playPCgame];//->Playing PC game now
        //Person<studyProtocol> *p2 = [Person new];编译器警告,因为Person类没有遵守studyProtocol协议
        Student<studyProtocol> *stu2 = [Student new];
        [stu2 studyOC];//->Studying OC now
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值