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

Sem*_*ush 0 inheritance objective-c

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

@property double x;
Run Code Online (Sandbox Code Playgroud)

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

@property double a, b;
Run Code Online (Sandbox Code Playgroud)

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

-(id)initWithAValue:andBValue:
Run Code Online (Sandbox Code Playgroud)

我被允许使用:

_a;  // same for b
[self setValue a]; // same for b
self.a;  // same for b and x
Run Code Online (Sandbox Code Playgroud)

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

mc0*_*c01 6

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

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

当您使用@property(之前使用过@synthesize,不再需要)时,它会自动生成getter,setter和支持ivar.ivar本身,取决于它声明的位置是@protected或者@private.回答这个问题,虽然有点旧,但对不同的可见性修饰符给出了一些见解.

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

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

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