Object C学习笔记15-协议(protocol)

  在.NET中有接口的概念,接口主要用于定义规范,定义一个接口关键字使用interface。而在Object C 中@interface是用于定义一个类的,这个和.NET中有点差别。在Object C中有一个协议(protocol) 的概念,这个和.NET中的interface类似。

  协议(Protocol) 在列出的方法在本类中并没有相应实现,而是别的类来实现这些方法,而定义协议必须使用protocol关键字。

 

  一. 如何定义protocol的定义

    如何使用XCode新建一个协议.h 文件

 

 

 

 

 

 

 

 

定义协议代码如下:

#import <Foundation/Foundation.h>

@protocol ProtocolCom <NSObject>

@required
-(void) eat;

@optional
-(void) write;

@end

定义协议代码

    从以上代码可以看到,我们可以了解到定义一个协议基本如下结构:

    @protocol protocolName<NSObject>

    @required

    //方法声明

    @optional

    //方法声明

    .......

    @end

从刚才的代码中,定义了一个名为ProtocolCom的协议,其中有两个方法 eat ,write;  上面也提到过了,protocol相当于.net中的interface 接口,接口就是用于定义规则的,但是Object C中的协议和.NET中的interface还是有点区别的,这里就涉及到@required,@optional 。 这两个标注在方法上面是有特殊含义的,这个后面详细说明。

#import <Foundation/Foundation.h>

@protocol ProtocolCom 

@required
-(void) eat;

@optional
-(void) write;

@end

修改协议代码

    从上面修改的代码对比来看,在协议定义后面缺少了<NSObject> ,这段代码仍然能够正常运行,其实<NSObject>也本身可以理解为ProtocolCom要遵循NSObject 协议,这个和.NET中一个类如果没有显示指定继承哪个类,那么默认就是继承的Object类的道理是一样的,所以这里可以省略。

    这里我在定义一个协议MyProtocol,这个协议必须遵循协议ProtocolCom协议。刚才上面已经了解到了协议后面跟<NSObject>,道理一样如果MyProtocol要遵循协议ProtocolCom就是用此种方式来实现,具体代码如下:

#import <Foundation/Foundation.h>
#import "ProtocolCom.h"

@protocol MyProtocol <ProtocolCom>

@required
-(void) setname;

@optional
-(void) setage;

@end

协议的"继承"

    在Object C 协议中并不习惯说继承,而是是用遵从或者遵循,比如A协议遵循B协议。这里专业上得术语可能不太准确,姑且这么说,先理解意思。

    然后我们是用一个新的类来实现协议MyProtocol中的所有方法。

#import <Foundation/Foundation.h>
#import "MyProtocol.h"

@interface Student : NSObject<MyProtocol>

@end

-------------------------------------------
#import "Student.h"

@implementation Student

-(void) write{
    NSLog(@"write");
}

-(void) eat{
    NSLog(@"eat");
}

-(void) setage{
    NSLog(@"Student---setage");
}

-(void) setname{
    NSLog(@"Student----setname");
}

@end

实现协议代码

    从以上代码可以看出类Student实现了协议MyProtocol,因为协议MyProtocol遵循协议ProtocolCom,所以协议MyProtocol有四个方法。所以在Student类中可以实现四个方法。

 

  二. 协议相关约束

    @required 用于表示协议中该方法必须在类中实现,默认[如果不加则默认为@required]

    @optional 用于表示协议中该方法在类中可以选择实现

    看到这里貌似比.NET中的要高级点,.NET中interface定义的所有方法在子类中都必须实现。如果用@required标识的方法在子类中没有实现那么编译编译会报错,提示该方法必须实现。而@optional则不会。下面这段代码就会存在问题:

#import "Student.h"
@implementation Student
-(void) write{
    NSLog(@"write");
}
-(void) eat{
    NSLog(@"eat");
}
-(void) setage{
    NSLog(@"Student---setage");
}
@end

未能实现所有@required标识的方法

    

   三. 同时遵循多个协议

    在.NET中一个类也可以实现多个接口,在Object C中同样如此,一个类可以实现遵循多个接口,基本语法如下:

    @interface className:parentName<ProtocolName1,ProtocolName2,...>

    ......

    @end

    虽然上面简单了点,但是还是能够看明白表达的意思,下面看一段代码说明:

    这里从新定义一个新的协议NewProtocol,里面有一个必须实现的方法getname

#import <Foundation/Foundation.h>
@protocol NewProtocol <NSObject>
@required
-(NSString*) getname;
@end

NewProtocol协议定义

    然后从新定义一个新的类Children,这个类必须遵循协议NewProtocol和协议MyProtocol ,具体代码如下:

#import <Foundation/Foundation.h>
#import "MyProtocol.h"
#import "NewProtocol.h"

@interface Children : NSObject<MyProtocol,NewProtocol>

@end

Children.h 遵循两个协议

    在Children.m代码中要实现两个协议中必须实现的方法

#import "Children.h"

@implementation Children

-(void) eat{
    NSLog(@"eat");
}

-(void) setname{
    NSLog(@"Student--setname");
}

-(NSString*) getname{
    return  @"qingyuan";
}
@end

Children.m实现两个协议代码

    下面使用测试代码,看看一个类遵循两个协议的效果:

Children *child=[[Children alloc] init];
        NSString *name=[child getname];
        NSLog(@"name=%@",name);
        [child eat];
        [child setname];

测试代码

    在上面的代码中可以正常运行,但是要注意如果可选择实现的方法没有去实现,而在这里去调用的话会报错。

 

  四. 正式协议和非正式协议

    说道正式协议和非正式协议,其实只要理解两个关键字@interface 和 @protocol 。先看看下面一个列子

#import <Foundation/Foundation.h>
#import "MyProtocol.h"
#import "NewProtocol.h"

@interface Children : NSObject<MyProtocol,NewProtocol>

-(void) love;

@end

在@interface 定义一个新方法

    在Children.h中定义了一个新的方法love,之前我们也一直这样写的,没有任何问题。再看下面一段代码

#import "Children.h"

@implementation Children

-(void) eat{
    NSLog(@"eat");
}

-(void) setname{
    NSLog(@"Student--setname");
}

-(NSString*) getname{
    return  @"qingyuan";
}
@end

Children.m实现的代码

    使用编译器编辑,代码并没有报错。在Children.m中没有love方法的实现。 这个和我们之前所见到的代码似乎有点不一样啊,有点不理解,理论上Children.m中应该实现love方法的。

    上面看到的这种情况,就好比Protocol中的@optional方法,是可以选择实现的,其实我们就称作@interface Children : NSObject 就是一个非正式协议。

刚才也注意到了,那是不是Protocol中的@optional标识的方法也就是非正式协议呢。在这里网络上有些争议,个人也没有完全明白,但是个人理解这个还是不一样的。@protocol是一种既定的规则,如果要做就必须遵循这种规则,而@interface有点象描述,用于描述类是干什么的. 而两者因为都可选择实现其他的方法,所以感觉有点类似。

 

  五. 协议总结

    Object C中有点特殊的时协议不引用任何类,任何类都可以实现已经定于好的协议。

bool flag1=[child conformsToProtocol:@protocol(NewProtocol)];
        NSLog(@"%d",flag1);

        bool flag2=[child conformsToProtocol:@protocol(MyProtocol)];
        NSLog(@"%d",flag2);

        bool flag3=[child conformsToProtocol:@protocol(ProtocolCom)];
        NSLog(@"%d",flag3);

判断某个类是否遵循协议

    从以上代码可以看得出,conformsToProtocol 方法用于判断某个类是否遵循某个协议,返回值为bool类型,即使协议是通过"继承"过来的也可以。

 

  本文到此结束,学习笔记可能有诸多问题,望请牛人勿喷,菜鸟的学习需要鼓励!

时间: 2024-10-24 11:53:49

Object C学习笔记15-协议(protocol)的相关文章

Object C学习笔记17-动态判断和选择器

当时学习Object C的时被人鄙视了一顿,说使用.NET的思想来学Object C就是狗屎:不过也挺感谢这位仁兄的,这让我学习的时候更加的谨慎.今天的学习笔记主要记录Object C中的动态类型相关内容. 首先还是和.NET先对比一下,.NET中存在一个关键字var ,这个估计用过.NET的都知道,除非没有接触过3.0以上版本的.在.NET中能够使用var来声明任何类型的局部变量,负责告诉编译器,该变量需要根据初始化表达式来推断变量的类型,而且只能是局部变量.但是这里要注意的时var 并不是一

Object C学习笔记10-静态方法和静态属性

在.NET中我们静态使用的关键字static有着举足轻重的作用,static 方法可以不用实例化类实例就可以直接调用,static 属性也是如此.在Object C中也存在static关键字,今天的学习过程使用到了这个关键字,在这里记录一下static的使用. 在Object C的语法中声明后的static静态变量在其他类中是不能通过类名直接访问的,它的作用域只能是在声明的这个.m文件中 .不过可以调用这个类的方法间接的修改这个静态变量的值.对于Object C中的类使用和定义在前面已经做过相应

Object C学习笔记21-typedef用法

在上一章的学习过程中遇到了一个关键字typedef,这个关键字是C语言中的关键字,因为Object C是C的扩展同样也是支持typedef的. 一. 基本作用 typedef是C中的关键字,它的主要作用是给一个数据类型定义一个新的名称,这些类型报告内部数据类型,比如int,char 还有自定义类型struct,enum等. typedef一般有两个作用:(1) 给某种类型顶一个定义比较容易记的名字,相当于别名;(2)简化较为复杂的类型声明.   二. typedef的使用 1. 定义新类型 语法

API Demos 2.3 学习笔记 (15)-- Views-&amp;gt;Radio Group

更多精彩内容,请点击阅读:<API Demos 2.3 学习笔记> 想想我们上学时候做的单项选择题,其中只有一个是正确答案.在做题的时候,我们只能选择一项.如果我们想在Android上设计一道单项选择题的话,可能就要用到RadioGroup了.RadioGroup常常和RadioButton一起使用.由一个RadioGroup包含若干个RadioButton,组成一个单项选择群组.我们在同一时间只能选中该组中的一个 RadioButton. RadioGroup的创建主要有两种方法: 1.在x

Object C学习笔记8-字符串NSString之二

5. 字符串是否包含 hasPrefix 判断字符串是否以某个字符串开头 hasSuffix 判断字符串是否以某个字符串结尾 NSString *str1=@"Object C学习正在进行中.... LOVE"; if([str1 hasPrefix:@"Object"]){ NSLog(@"字符串:%@是以%@开头",str1,@"Object"); } if([str1 hasSuffix:@"LOVE"

Flash/Flex学习笔记(15):FMS 3.5之远程共享对象(Remote Shared Object)

FMS中的"远程共享对象"可以让多个Client端的flash应用共享同一个全局对象,并且当客户端中的任何一个改变该对象时,系统会自动将该对象回发到FMS服务器,同时FMS服务器也会将该对象重新广播到所有客户端.   说得更通俗一点:如果二个机器上浏览这种flash应用,在一台机器上所做的操作,将会在另一台机器同步体现出来.   这个能干嘛? 电子教室(比如老师在一台机器上演示教学,其它所有机器上能同步刷新),互动游戏(比如:游戏中的情侣可以在异地同时装修自己的房子),需要在服务端保存

Object C学习笔记23-继承,重写,重载

前面的学习都一直在使用Object C对象,但是没有具体总结过Object C中的对象使用特性,这里简单总结一下. 一.  继承 在面向对象编程中,子类可以通过继承得到父类的可以继承的的属性和方法,在Object C中也同样如此. 先定义一个Person类,并且定义几个属性和一个方法: #import <Foundation/Foundation.h> @interface Person : NSObject{ NSString *name; int age; NSArray *itmes;

Object C学习笔记6-如何在Windows环境搭建Object C开发环境

1. 安装编译环境 Object C和其他很多语言一样,都需要有一个编译器.Object C 是在GCC下编译的.GCC(GNU Compiler Collection,GNU编译器集合),是一套由 GNU 开发的编程语言编译器.很多人想到学习Object C就想到mac电脑,想到XCode开发工具.其实在Windows环境一下也可以编译Object C. 首先下载Windows版本的GCC编译器,下载地址:http://wwwmain.gnustep.org/resources/downloa

Object C学习笔记9-字符串NSMutableString

  NSMutableString类继承自NSString,所以在NSString中的方法在NSMutableString都可以使用. NSMutableString和NSString的区别在于NSMutableString是动态的字符串,可以动态的添加,修改,删除等.在前面提到了就和.NET中的string和StringBuilder的区别一样.   1. 添加字符串 向字符串末尾添加字符串可以使用appendString方法和appendFormat方法.appendString方法主要用于