美文网首页初见
iOS 中的协议 — @protocol

iOS 中的协议 — @protocol

作者: 大成小栈 | 来源:发表于2020-06-10 17:55 被阅读0次

    1. 关于Protocol

    在使用OC开发iOS程序的过程中经常会用到Protocol,定义一个Protocol的语法格式如下:

    @protocol HumanProtocol <NSObject>
    
    @required
    - (void)name;
    - (void)age;
    
    //@optional
    // ...
    
    @end
    

    它类似于java的接口interface,接口就是一堆方法的声明,没有实现。一般一个类可以遵循一个或多个协议,任何类只要遵循了协议就相当于拥有了这个协议中所有的方法声明。Protocol可以定义在一个类的头文件上部,并直接应用在该类中(如作为delegate功能使用时),Protocol也可以单独定义到一个类中,作为多个不同类来遵循并实现的interface。

    #import <Foundation/Foundation.h>
    
    @protocol HumanProtocol <NSObject>
    
    @required
    - (void)name;
    - (void)age;
    
    //@optional
    // ...
    
    @end
    
    @interface Worker : NSObject
    
    @property (nonatomic, copy) id<HumanProtocol> delegate;
    
    @end
    
    ----------------------
    
    #import "Peter.h"
    #import "Worker.h"
    
    @interface Peter : NSObject <HumanProtocol>
    
    @end
    
    @implementation Peter
    
    // 实现定义的方法
    - (void)name {
    }
    - (void)age {
    }
    
    @end
    
    

    #import <Foundation/Foundation.h>
    #import "HumanProtocol.h"
    @interface Peter : NSObject <HumanProtocol>
    
    @end
    
    @implementation Peter
    
    // 调用协议变量,或实现协议方法
    
    @end
    
    

    2. 使用示例

    <NSObject>是一个基协议,每个新协议都需要遵循。@protocol是定义一个协议的注解,其中,@required表示这个方法必须被实现,@optional表示这个方法不一定要被实现。

    简单应用场景:
    一个人需要一个app,这个app必须有学习、买东西、分享等功能。

    思路:
    1、需要创建一个人和APP
    2、需要创建一个Protocol来描述这些功能
    3、人拥有的APP要实现这些功能
    4、APP需要遵循这个Protocol且实现它

    #import <Foundation/Foundation.h>
    @protocol DoSomethingProtocol <NSObject>
    - (void)buySomething;
    - (void)studyEnglish;
    - (void)shareInfo;
    @end
    ----------------------------
    #import <Foundation/Foundation.h>
    #import "DoSomethingProtocol.h"
    @class APP;
    @interface Person : NSObject
    //拥有的APP要实现Protocol的功能
    @property (nonatomic,strong) APP<DoSomethingProtocol> *app;
    @end
    ----------------------------
    #import <Foundation/Foundation.h>
    #import "DoSomethingProtocol.h"
    @interface APP : NSObject<DoSomethingProtocol>
    @end
    
    #import "APP.h"
    @implementation APP
    - (void)buySomething {
        NSLog(@"%s",__func__);
    }
    - (void)shareInfo {
        NSLog(@"%s",__func__);
    }
    - (void)studyEnglish {
        NSLog(@"%s",__func__);
    }
    @end
    ----------------------------
    Person *p = [[Person alloc]init];
    APP *app = [[APP alloc]init];
    //赋值的时候就会判断app是否是符合协议的app,如果app没有遵循协议就会报警告
    p.app = app;
    
    //判断app是否有实现协议内容
    if([p.app respondsToSelector:@selector(buySomething)]){
            [p.app buySomething];
    }
    if ([p.app respondsToSelector:@selector(studyEnglish)]) {
            [p.app studyEnglish];
    }
    if ([p.app respondsToSelector:@selector(shareInfo)]) {
            [p.app shareInfo];
    }
    

    3. 需要注意的几个点

    • 协议与继承的区别

    继承之后默认就有实现,而protocol只要声明没有实现;相同类型的类可以使用继承,但是不同类型的类只能使用protocol;protocol可以用于存储方法声明,可以将多个类中共有的方法抽取出来,以后让这些类遵守协议即可

    • Protocol 与 Category 的区别

    Category给一个类可以扩充方法,既有申明也有实现,而Protocol只有声明,没有实现;Category可以声明方法,不能声明属性。而Protocol都可以,Protocol可以用@property形式声明属性,只不过在Protocol中声明的属性,只有对应的setter/getter方法声明,并没有生成对应的成员变量。

    Protocol:

    @protocol SportProtocol <NSObject>
    @property (nonatomic,copy) NSString *sportType;
    - (void)playFootball;
    - (void)playBasketball;
    - (void)run;
    @end
    

    实现类:

    #import <Foundation/Foundation.h>
    #import "SportProtocol.h"
    @interface Person : NSObject<SportProtocol>
    @end
    
    #import "Person.h"
    @implementation Person
    @synthesize sportType=_sportType;
    
    - (void)readSportType{
       NSLog(@"%@",_sportType);
    }
    @end
    

    上面方法中主要用到了@synthesize sportType=_sportType, 意思是说,sportType 属性为 _sportType 成员变量合成访问器方法。

     Person *p =[[Person alloc]init];
     p.sportType = @"sport";
     [p readSportType];
    

    父类遵守了某个类的Protocol,那么子类也会自动遵守这个Protocol

    #import <Foundation/Foundation.h>
    #import "SportProtocol.h"
    @interface Person : NSObject<SportProtocol>
    @end
    ----------------------
    #import "Person.h"
    @interface Student : Person
    @end
    ----------------------
    Student *stu = [[Student alloc]init];
    [stu playBasketball];
    一个类可以遵守多个Protocol
    #import <Foundation/Foundation.h>
    #import "SportProtocol.h"
    #import "StudyProtocol.h"
    @interface Person : NSObject<SportProtocol,StudyProtocol>
    @end
    Protocol又可以遵守其他Protocol,只要一个Protocol遵循了其他Protocol,那么这个Protocol就会自动包含其他Protocol的声明
    #import <Foundation/Foundation.h>
    #import "BaseProtocol.h"
    @protocol StudyProtocol <BaseProtocol>
    - (void)studyEnglish;
    - (void)studyChinese;
    @end
    

    相关文章

      网友评论

        本文标题:iOS 中的协议 — @protocol

        本文链接:https://www.haomeiwen.com/subject/svbutktx.html