您的位置:首页 > 移动开发 > Objective-C

Object-C学习笔记-Protocol(协议)与非正式协议

2012-08-06 20:47 316 查看
// Box.m
#import "Box.h"

@implementation Box
// ...省略代码
- (void) print:(id<Printable>)pObj {
[pObj print];
}
// ...省略代码
@end


谈一些个人的观点,感觉在Objective-C中的通常用来创建类的@interface反而不像传统意义上的接口,更像是类的提纲。

本文所提及的协议则更像传统意义上的接口。

分析以下情况

// Printable.h
#import <Foundation/Foundation.h>

@protocol Printable <NSObject>
- (void) print;
@end


// Drawable.h
#import <Foundation/Foundation.h>

@protocol Drawable <NSObject>
- (void) draw;
@end


// Box.h
#import <Foundation/Foundation.h>

@interface Box <Drawable, Printable>
{
double width;
double height;
}
- (double) area;
- (void) print;
- (void) draw;
@end
// Box.m
#import "Box.h"

@implementation Box
- (double) area {
return width * height;
}
- (void) print {
NSLog(@"I am instance of Box -> w:%g h:%g", widht, height);
}
- (void) draw {
NSLog(@"Box -> Draw");
}
@end

上例中Box类遵循了两套协议Drawable和Printable

所以在@implementation阶段需要实现这两个协议中的方法来遵守协议

这样看来是不是更像传统意义上的接口?

但这里其实就算在@implementation阶段不实现接口编译照样可以通过,只是回得到一个警告,告诉你Box还有未实现的方法,不遵守协议的代价相当小。

甚至如果没有实现Box的@interface的所有方法依然可以编译通过,但一个类可以遵循多个协议。

在@protocol中可以使用@require指令和@optional指令来说明该接口是否应该被遵循。不加指令默认是@require的。

上面的Printable协议与下面等价

#import <Foundation/Foundation.h>

@protocol Printable <NSObject>
@required
- (void) print;
@end


而所说的非正式协议则指的是包含在@optional指令中的方法,比如随便在Printable中加一些required和optional的方法

#import <Foundation/Foundation.h>

@protocol Printable <NSObject>
@required
- (void) print;
- (void) foo;
- (void) bar;
@optional
- (void) foobar;
- (void) barfoo;
@end


很明显print/foo/bar为必须实现,不实现的代价就是警告

而foobar/barfoo则可选实现,不实现连警告都不会出现

如果一个协议仅包含@optional部分则这个协议便是传说中的非正式协议

在定义某个方法时可以指定这个方法只接受遵循某种协议的参数,类似给Box增加一个类方法print

// Box.h
#import <Foundation/Foundation.h>

@interface Box <Drawable, Printable>
// ...省略代码
+ (void) print:(id<Printable>)pObj;
// ...省略代码
@end


// Box.m
#import "Box.h"

@implementation Box
// ...省略代码
+ (void) print:(id<Printable>)pObj {
[pObj print];
}
// ...省略代码
@end


在参数类型中采用(id<Protocol>)来说明该参数遵循了哪个协议

在方法体中则直接可以调用该对象的协议内方法,而无需关心这个pObj是一个Box还是一个Circle

虽然这个print的方法设计不太合理,但纯粹是演示之用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: