1
2
3
4
5
6
7
8
9
|
#import <Foundation/Foundation.h>
@interface
Sample :
NSObject
{
}
-(
void
) HelloWorld;
@end
|
1
2
3
4
5
|
@protocol
IQuery
-(
void
) Query:(
NSString
*) sql;
@end
|
1
2
3
4
5
6
7
8
|
#import <Foundation/Foundation.h>
#import "IQuery.h"
@interface
DBQuery :
NSObject
<IQuery> {
}
@end
|
1
2
3
4
5
6
7
8
9
10
|
#import "DBQuery.h"
@implementation
DBQuery
-(
void
) Query:(
NSString
*)sql
{
NSLog
(@
"Query is called. sql:%@"
,sql);
}
@end
|
1
2
3
4
5
6
7
8
9
|
@protocol
IQuery
@required
-(
void
) Query:(
NSString
*) sql;
@optional
-(
void
) HelloWorld;
@end
|
有了@optional关键字以后,其实“非正式协议”在语义上完全可以被“正式协议”所取代,事实上Cocoa中的非正式协议都在逐渐被标有@optional方法的正式协议所代替。
如果你在XCode的代码中,选中NSObject,右击-->Jump to Definition,会发现NSObject其实就是一个interface或protocal
选择protocal NSObject 继续,会看到NSObject.h文件中关于protocal NSObject的定义
同样的,你还可以看到interface NSObject的定义
从这里可以看到,非正式协议的interface NSObject其实最终采用的还是正式协议protocal NSObject.
也就是说,在obj-c的OO世界中,身为万物之祖的NSObject其实也就一个"正式协议”,所以从NSObject派生出的所有类,都只是在遵守一个或多个协议而已。
另一个话题泛型
在obj-c中,一切皆为指针。前面的学习中,我们已经接触到了一种特殊的类型id,它可以认为是一种特殊的指针:可以指向任何类型的对象。id 再加上正式协议,能够达到形似c#中泛型的效果(注:只是形似,并非神似)
1
2
3
4
5
6
7
8
9
|
#import <Foundation/Foundation.h>
#import "IQuery.h"
@interface
DBQuery :
NSObject
<IQuery> {
}
-(
void
) test:(
id
<IQuery>) obj;
@end
|
注意这里的 -(void) test:(id<IQuery>) obj; 这表明test方法接受一个任意类型的对象做为参数,但是该参数对象必须实现接口IQuery(也可以说成该参数对象必须采用正式协议IQuery),是不是跟c#中的
void test(List<IQuery> obj) 长得很象?