【问题标题】:override property from superclass in subclass覆盖子类中超类的属性
【发布时间】:2013-06-15 19:16:14
【问题描述】:

我想覆盖在超类中声明的 NSString 属性。当我尝试使用默认 ivar(它使用与属性相同但带有下划线的名称)来执行此操作时,它不会被识别为变量名。它看起来像这样......

超类的接口(我没有在这个类中实现getter或setter):

//Animal.h
@interface Animal : NSObject

@property (strong, nonatomic) NSString *species;

@end

子类中的实现:

//Human.m
@implementation

- (NSString *)species
{
    //This is what I want to work but it doesn't and I don't know why 
    if(!_species) _species = @"Homo sapiens";

    return _species;

}

@end

【问题讨论】:

标签: ios objective-c


【解决方案1】:

只有超类可以访问 ivar _species。您的子类应如下所示:

- (NSString *)species {
    NSString *value = [super species];
    if (!value) {
        self.species = @"Homo sapiens";
    }

    return [super species];
}

如果当前根本没有设置该值,则将其设置为默认值。另一种选择是:

- (NSString *)species {
    NSString *result = [super species];
    if (!result) {
        result = @"Home sapiens";
    }

    return result;
}

如果没有值,这不会更新值。它只是根据需要返回一个默认值。

【讨论】:

  • 我试图了解发生了什么:)。为什么不返回第一个中的[超级物种]只是返回零?
  • 在第一个代码块中,“超级物种”被调用了两次。你想知道哪一个?
  • 第二个【超级物种】。
  • 由于调用了self.species = @"Homo sapient";,它不返回nil
  • 这个解决方案要求属性是可读写的,因此任何人都可以随时更改子类实例的种类。不太好。
【解决方案2】:

要访问超类变量,必须将它们标记为@protected,此类变量只能在类及其继承者内部访问

@interface ObjectA : NSObject
{
    @protected NSObject *_myProperty;
}
@property (nonatomic, strong, readonly) NSObject *myProperty;
@end

@interface ObjectB : ObjectA
@end

@implementation ObjectA
@synthesize myProperty = _myProperty;
@end

@implementation ObjectB
- (id)init
{
    self = [super init];
    if (self){
        _myProperty = [NSObject new];
    }
    return self;
}
@end

【讨论】:

  • 你应该通过公共接口调用超类的属性/方法,而不是做灰盒,如rmaddy所示。
猜你喜欢
  • 2015-09-12
  • 1970-01-01
  • 1970-01-01
  • 2019-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-13
  • 1970-01-01
相关资源
最近更新 更多