了解私有实例变量

时间:2013-07-10 04:38:54

标签: objective-c

我很难通过示例了解私有实例变量。在阅读了私有实例变量之后,我去了Xcode并试图验证它们是如何工作的。

在我正在阅读的书中,它指出如果你在超类的实现文件中声明一个实例变量,那么实例变量将是私有的,并且对于子类是不可访问的。

我试着证明它没有运气就做了以下事情。

/** SuperClass interface file**/
#import <Foundation/Foundation.h>

@interface ClassA : NSObject

-(void) setX;
-(void) printX;

@end

/**SuperClass implementation file **/
#import "ClassA.h"

@implementation ClassA
{
    int x;
}

-(void) setX
{
    x = 100;
}

-(void) printX
{
    NSLog(@" x is equal to %i", x);
}

@end

/** interface file of subclass **/
#import "ClassA.h"

@interface ClassB : ClassA

@end



/**Main file **/
#import "ClassA.h"
#import "ClassB.h"


int main(int argc, const char * argv[])
{

    @autoreleasepool


    { 

        ClassA * a;
        a = [[ClassA alloc] init];

        ClassB * b;
        b = [[ClassB alloc] init];


        [b  setX];
        [b printX];



    }
    return 0;

}

该程序打印以下内容:  x等于100

不是“x”私有实例变量,对象“b”不可访问,因为“x”在superClass“a”的实现文件中声明,而“b”是子类?

书中说“子类直接访问的实例变量必须在接口部分声明,而不是在实现部分...在实现部分声明或合成的实例变量是私有实例变量而不是可以通过子类直接访问。“

真的很困惑。

2 个答案:

答案 0 :(得分:3)

方法setXprintX是公开且可见的,因此可以在ClassB的实例上调用。由于它们是公开的,因此ClassB也可以调用它们,就像这样。

@implementation ClassB

- (void)fig {
   [self setX];
}

@end

不能完成的是ClassB直接访问值x。像这样:

@implementation ClassB

- (void)foo {
   NSLog(@"x is now %i", x);
}

@end

ClassB没有直接访问x,但它通过超类方法间接访问x。这种间接访问是一种面向对象的编程概念,称为封装。

答案 1 :(得分:0)

Ivars默认具有@protected属性,意味着子类可以访问它们。要将ivar声明为private,请在ivar声明之前使用@private属性:

@interface ClassA : NSObject
{
@private
    int x;
}

如果你在@implementation部分声明你的ivars,它们对子类可见的唯一方法是在子类中导入.m文件,但你不能使用它们,因为它们是私有的。 / p>

或者根本不使用ivars,因为Objective-C属性现在自动创建ivars。如果您需要私有属性,可以通过.m文件中的匿名类别声明它,如下所示:

@interface MyClass ()

@property (nonatomic) NSInteger x;

@end

<强>更新 我想我明白了你的困惑。公共和受保护的ivars由子类继承,可以直接作为子类的实例变量访问,不需要使用子类中的访问器方法。