Objective C - 子类中的窄实例变量类型?

时间:2010-11-22 17:07:00

标签: iphone ios subclassing

是否可以缩小子类中ivar的允许类型。像这样:

@interface person: NSObject {
  NSArray *friendArray;
}

@interface mutablePerson: person {
  NSMutableArray *friendArray;
}

我刚尝试了那个确切的代码,Xcode给了我一个编译错误。我想知道是否有办法绕过它。

我正在研究的项目将会出现很多这种情况。我知道我可以使用强制转换来使代码工作。但如果我这样做,我会做很多演员表,我想知道是否有更好的方法。

4 个答案:

答案 0 :(得分:1)

不,你根本不能重新声明伊娃。但是,您可以创建基于新方法的属性,而无需创建新的ivar。

@property (nonatomic, copy) NSMutableArray* mutableFriends;

@implementation MutablePerson

- (NSMutableArray*)mutableFriends {
  return (NSMutableArray*)friendArray;
}

- (void)setMutableFriends:(NSMutableArray*)friends {
  self.friendsArray = [friends mutableCopy];
}

@end

答案 1 :(得分:0)

@class根本没有意义......它应该是@interface。所以第一个错误纯粹是语法上的。

不,你不能改变伊娃的类型。这有一个很好的理由:缩小它(就像你一样)是行不通的,因为父类可能依赖于不同的实现。扩大它不能很好地工作(主要是出于类似的原因。

答案 2 :(得分:0)

如果编译器说'不'那么这就是你的答案。我会使用访问者:

//Person
-(NSArray *)friends;


//MutablePerson
-(void)addFriend:(person *)friend;

MutablePerson中,您可以声明另一个数组来存储friends,或者您可以直接在addFriend:中访问ivar:

-(void)addFriend:(person *)friend
{
    _friendsArray = [_friendsArray arrayByAddingObject: friend];
}    

直接访问ivars并不聪明。我会重新考虑你的课堂设计。拥有可变和不可变版本的人的理由是什么?

答案 3 :(得分:0)

我结束了覆盖setter以断言所设置的对象是合适的类型,并创建一个新的只读getter,如下所示:

@interface MutablePerson {
}

@property (readonly) NSMutableArray *mutableFriendArray;

@implementation MutablePerson

-(NSMutableArray *) mutableFriendArray {
  NSMutableArray *ret = (NSMutableArray *)[super friendArray];
  NSAssert ([ret isKindOfClass: [NSMutableArray class]], @"array should be mutable");
  return ret;
}

-(void) setFriendArray: (NSMutableArray *) array {
  NSAssert ([array isKindOfClass: [NSMutableArray class]], @"array should be mutable");
  [super setFriendArray: array];
}