为什么我不能在子类中使用超类的属性(Objective-C)

时间:2014-10-24 15:59:48

标签: objective-c inheritance

我在一个类中声明了一个属性:

@property double x;

然后我创建了该类的子类,其中我声明了另外两个属性:

@property double a, b;

然后我在子类中创建了一个init方法:

-(id)initWithAValue:andBValue:

我可以使用:

_a;  // same for b
[self setValue a]; // same for b
self.a;  // same for b and x

现在,当我尝试使用x属性时,我只能使用[self setValue x]而我不能使用_x。为什么呢?

1 个答案:

答案 0 :(得分:6)

您可以获取/设置属性,您无法直接访问它后面的实例变量/后备存储,即使它们属于子类,您通常也不会这样做。

_x是实例变量或ivar。 self.x是属性,可以通过使用@property声明x时创建的getter / setter方法进行访问。

当您使用@property(以前与@synthesize一起使用时,不再需要)时,它会自动生成getter,setter和支持ivar。 ivar本身,取决于声明的位置创建为@protected@private。回答this question,虽然有点旧,但要对不同的可见性修饰符有所了解。

如果在公共.h文件中声明@property double x,默认情况下它将是@protected,这意味着访问器方法和ivar应该对超类和子类的实例可见,但是而不是其他外部类的实例。

如果您在类扩展中声明了相同的@property或.m中的@implementation块(仅展示您真正需要的内容),则默认为@private,这意味着ivar只能由那个确切类的实例访问 - 而不是子类实例。这使得只有getter / setter方法暴露给子类。

如果选择,您可以覆盖这些默认值,但通常最好使用accessor / mutator方法&不直接与伊瓦尔斯打交道。这是设计使然,因为您想要精确控制其他对象(甚至是子类实例)如何访问/操作变量。