在继承一个类时,我想同时继承父类的代理(delegate),因为子类现在有了额外的功能。如何最好地实现这样的操作?如果我只是在子类中声明另一个同名的代理属性,那么我将会收到警告:“属性类型'id'与从'ParentClass'继承的类型'id'不兼容”。
考虑以下例子,它会产生警告:
// Class A
@protocol ClassADelegete;
@interface ClassA : NSObject
@property (nonatomic, weak) id<ClassADelegete> delegate;
@end
@protocol ClassADelegete <NSObject>
- (void)classADidSomethingInteresting:(ClassA *)classA;
@end
// Class B
@protocol ClassBDelegete;
@interface ClassB : ClassA
@property (nonatomic, weak) id<ClassBDelegete> delegate; // Warning here
@end
@protocol ClassBDelegete <ClassADelegete>
- (void)classBDidSomethingElse:(ClassB *)classB;
@end
有两种解决方法可以消除警告:
1)在子类中,在类定义之前放置协议定义。这就是UITableView.h
中的UITableViewDelegate
所做的:
// Class B
@class ClassB;
@protocol ClassBDelegete <ClassADelegete>
- (void)classBDidSomethingElse:(ClassB *)classB;
@end
@interface ClassB : ClassA
@property (nonatomic, weak) id<ClassBDelegete> delegate;
@end
2)在子类中,同时添加原始协议和新协议:
// Class B
@protocol ClassBDelegete;
@interface ClassB : ClassA
@property (nonatomic, weak) id<ClassADelegete, ClassBDelegete> delegate;
@end
@protocol ClassBDelegete <ClassADelegete>
- (void)classBDidSomethingElse:(ClassB *)classB;
@end
跟随 NSTableView
和 NSOutlineView
的例子。
NSOutlineView
是 NSTableView 的子类,并为其 dataSource
和 delegate
定义了自己的协议。
NSTableView
通过以下方式声明其代理:
- (void)setDelegate:(id <NSTableViewDelegate>)delegate;
- (id <NSTableViewDelegate>)delegate;
以及 NSOutlineView
:
- (void)setDelegate:(id <NSOutlineViewDelegate>)anObject;
- (id <NSOutlineViewDelegate>)delegate;
显然,编译器对于裸方法声明比属性声明更宽容。
与NSTable/OutlineView不同,您可能希望使子类的协议继承自基类的协议,例如:
@protocol SpecializedProtocol <BaseProtocol>
这可能取决于情况。
@dynamic delegate;
。 - boog