到目前为止,我们已经在类的头文件中声明过属性,变量及方法。头文件是类声明它的属性及方法的地方,这样其他的对象才能够知道如何和类进行交互。

  然而,不是所有的属性或方法都需要在类的头文件中声明。有的属性或方法只是该类或其类实例才需要使用的。涉及实现细节的属性或方法最好在类扩展(class extension)中声明。类扩展是一组私有的声明。只有类和其类实例才能使用在类扩展中声明的属性,实例变量或方法。

  例如,BNREmployee的officeAlarmCode属性应该是私有的。BNREmployee对象需要获取自己的alarm code(紧急码),而非BNREmloyee对象则不需要知道alarm code,也不应该知道。要做到这点,可以将officeAlareCode在(BNREmployee.h)头文件的声明一道类扩展中。

  通常,类扩展时添加在类实现文件中,实现方法的@implementation之上的。在BNREmployee.m中,创建一个类扩展。然后在类扩展中声明officeAlarmCode属性:

  类扩展以@interface开始,@end结束。实际上,类扩展和头文件看上去很像,它们都是"接口(interface)"。然而,在类扩展中,和头文件中使用冒号和父类的名称不同,它使用的是一对空的括号。

  在BNREmloyee.h中,删除officeAlarmCode声明:

  构建并运行程序,运行结果不会发生任何变化。然而,将officeAlarmCode声明移动类扩展中有两个相关的影响。

  首先,非BNREmployee对象不能再看到这个属性了。例如,一个非BNREmployee实例对象不能再获取到BNREmployee的officeAlramCode属性;

  其次,现在BNREmployee头文件的声明少了,因此变简单了一些。这是一件好事。头文件其实是一个告示牌,它的工作就是告诉其他开发者如何使用这个类。而太多的内容会给阅读和使用增加困难。

 

隐藏可变属性(Hiding mutability)

  现在介绍在类扩展做声明,而不是在类头文件做声明的另一个不同的例子。在BNREmployee.h中,声明一个assets属性,它是一个NSArray对象,一个addAsset:方法及一个_assets实例变量,它是一个NSMutableArray对象。开发者会在头文件公布属性和实例变量,但不确定你是否希望其他非BNREmployee实例对象或其他开发者使用它们。

  现在你知道了类扩展,那解决方法就很简单了:将_assets实例变量移到BNREmployee的类扩展中。在BNREmployee.m中,增加以下声明:

  

  现在大家知道assets是一个NSArray实例。非BNREmployee对象就要使用addAsset:方法来操作这个数组。实际上,它是一个NSMutableArray实例,可变版本的assets实例只有BNREmployee对象才知道。

 

头文件与继承(Headers and in heritance)

  子类无法获取父类的类扩展。BNREmployee是BNRPerson的子类,它会导入父类的头文件BNRPerson.h。因此BNREmployee知道在BNRPerson头文件声明的内容,但无法知道在BNRPerson的类扩展中声明的内容。

 

头文件与生成的实例变量(Headers and generated instance variables)

  在类的头文件声明属性的时候,其他对象职能看到属性的存取方法。非BNREmloyee对象(包括其子类)无法直接获取属性生成的实例变量。

  例如,如果BNRPerson.h声明了以下属性:

@property(nonatomic)NSMutableArray*friend;

  在BNREmployee.m中,即使BNREmployee是BNRPerson的子类,也不能获取到_friends实例变量:

[_friends addObject:@"susan"];//错误!

  然而,你可以使用它的存取方法:

[self.friends addObject:@"susan"];

这里我并不是十分理解;