能,一般用的场合是,有两个类A和B,如果A和B不是继承关系,想给A和B增加几个相同的属性,可以实现一个协议C,加个属性,然后让A和B都遵循C协议就可以了。当然协议中只是声明了属性,在A和B里还要手动实现以下setter和getter方法才行。
协议中能够声明方法,以及属性。然后问题就来了,不是不能定义成员变量的吗?
对,的确不能定义成员变量,但是属性是什么?属性包含了三个东西:成员变量、setter方法、getter方法。在类中定义的属性,当然三者都有,然而协议中定义的属性只有获取和设置方法,没有成员变量,这就要求该协议的遵守者必须自己写出setter和getter方法的实现。但是有一种情况是不需要的,那就是遵守者本来就有这个属性,此时系统会为这个属性自动生成设置获取方法,既然已经实现了,那么遵守者就没必要去实现协议中的这个属性了。
尽管可以实现“伪属性”,但是,我们还是应该尽量把属性定义在主接口中,而不应该定义在协议中。
还有一点,也是很重要的一点,为什么自定义的协议后面会有这么一个东西<NSObject>?
协议也能继承。既可以继承自自定义的协议,也可以继承自系统的协议。
我们在定义协议的时候,一般都是直接继承自<NSObject>,为什么系统要默认让协议继承自这个协议呢?
因为这个协议中定义了一些基本的方法,由于我们使用的所有类都继承NSObject这个基类,而这个基类遵守了<NSObject>这个协议,那么也就实现了其中的那些方法,这些方法当然可以由NSObject及其子类对象调用,但是在不知道遵守者类型的时候需要用到id <协议名>这样的指针,这个指针在编译期并不知道自己指向哪个对象,唯一能调用的便是协议中的方法,然而有时候又需要用一些基本的方法,比如要辨别id <协议名>这个指针所指的对象属于哪个类,就要用到-isMemberOf:这个方法,而这个方法是<NSObject>这个协议中的方法之一,所以,我们自定义的协议都需要继承<NSObject>。本段一开始便说道:<NSObject>中的方法在NSObject基类中实现了,那么无需再关心实现了,直接调用<NSObject>中的方法吧。
需要注意的问题
根据约定,框架中后缀为Delegate的都是Protocol,例如UIApplicationDelegate,UIWebViewDelegate等。
Protocol本身是可以继承的,比如:
@protocol A
-(void)methodA;
@end
@protocol B <A>
-(void)methodB;
@end
如果你要实现B,那么methodA
和methodB
都需要实现。
Protocol是与任何类都无关的,任何类都可以实现定义好的Protocol,如果我们想知道某个类是否实现了某个Protocol,那么我们可以用conformsToProtocol:
方法进行判断:
[obj conformsToProtocol:@protocol(ProcessDataDelegate)]