定义类
Objective-C类定义有一个接口和一个实现部分。与C++有相似的地方,但两个稍微有些混。
Objective-C中的接口仅定义位并且明确的需要公开。对于实现的原因,这包括私有实例变量在大部分的实现中,因为你无法继承一个类除非你知道它多大。最近的一些实现,象Apple的64位运行时则没有这种限制。
Objective-C对象的接口如下:
{
@private
int integerivar
@public
id anotherObject;
}
+ (id) aClassMethod;
- (id) anInstanceMethod:(NSString*)aString with:(id)anObject
@end
第一行包含3个部分。标识符AnObject 是新类的名字。冒号后面的名字是NSObject。(这是可选的,但每一个Objective-C 对象都应拓展NSObject)。在括号内的名字是协议——与Java中的接口相似——通过类来实现。
正如C++实例变量(C++中的域)可以存取修饰符,不象C++,这些修饰符以@为前缀是为了避免与C标识符冲突。
Objective-C不支持多继承,所以只有一个父类。所以,对象第一部分的布局总是与父类实例的布局一致。这在过去常常定义为动态,意味着改变类中实例变量需要它所有子类重新编译。在较新的运行时这种限定并不要求,在存取实例实例变量上开支稍微大些。这种决策的另一个影响就是Objective-C其他特性中的一个。
{
@defs(AnObject);
};
@def表示着对特定对象所有域都插入这种结构,所以struct_AnObject 和AnObject类的实例有着相同的内存结构。举个例子来说,你可以通过这种规则可以直接存取实例变量。一个通常的用法就是允许C函数直接操作Objective-C对象,是基于性能原因。
正如我前面暗示的,与这个特性相关的另一件事就是可以在堆栈上创建对象。因为结构和对象在[FS:PAGE]内存布局中有着相同的结构,你可以简单的创建结构,设置他的指针指向正确的类,然后映射一个指针指向一个对象指针。然后你可以当做对象来使用,虽然你不得不小心没有什么可以保持指针不越界。(现实世界中我从没有使用这种方法,仅仅理论上可能。)
不象C++,Objective-C没有私有的或受保护的方法。Objective-C对象上的任何方法可以被其他对象调用。如果你在接口中没有声明方法,就是非正式私有的。将会得到运行时警告:对象不回应这种消息,但是你任然可以调用它。
接口和C中头部声明很相似。但它仍然需要一个实现,这并不奇怪,可以使用@implementation来定义。
+ (id) aClassMethod
{
...
}
- (id) anInstanceMethod:(NSString*)aString with:(id)anObject
{
...
}
@end
注意参数类型是特定的,在括号里。这是从C重用映射语法来展示值映射到类型;他们可能不是类型。准确来说当映射时应用相同的规则。这意味着映射在不兼容对象指针类型间会导致一个警告(不是错误)。