B.8.4 对象声明
一般格式:
classNamevar1,var2,……;
这个格式将var1、var2……定义为className类的对象。注意,该格式声明了一些指针变量,而且不会为每个指针对象中包含的实际数据保留存储空间。声明
Fraction*myFract;
将myFract定义为Fraction对象,或从技术上讲,是将myFract定义为指向Fraction对象的指针。要想给Fraction的数据结构分配实际的存储空间,通常会调用该类的alloc或者new方法,如下:
myFract=[Fraction alloc];
这条语句为Fraction对象和指向它的指针保留了足够的存储空间,这个指针将被返回并指派给myFract。变量myFract通常称作一个对象或Fraction类的实例。由于定义了位于根对象中的alloc方法,所以最新分配的对象的所有实例变量将被设为0。然而,但这并不意味着已经对该对象进行了正确的初始化,并且应该在使用这个对象之前调用它的初始化方法(例如init)。
因为变量myFract已经被显式地声明为Fraction类的一个对象,所以可以说该变量是静态类型的。通过参照关于方法的正确使用以及它们的参数和返回类型的类定义,编译器可以检查所使用的静态类型的变量的一致性。
id对象声明
一般声明:
id<protocol,……>var1,var2,……;
这个格式将var1、var2……声明为一个不确定类的对象,这个类与尖括号中列出的(多个)协议是一致的。协议列表是可选的。
任何类对象都可以指派给id变量,反之亦然。如果列出一个或多个协议,编译器将使用一种一致的方式—即,与正式协议中声明的方法的相关参数和返回类型相一致,来检查那些列出的协议所使用的方法以及所使用的任何声明的变量。
例如,在语句
id<MathOps>number;
……
result=[number add:number2];
中,编译器将检查MathOps协议是否定义了一个add:方法。如果定义了这个方法,随后编译器就会检查这个方法的参数和返回类型的一致性。因此,如果此方法接受一个整型参数,而你正在给它传递一个上述的Fraction对象,则编译器将发出警告。
系统会跟踪每个对象所属的类;因此,系统可在运行时确定对象的类,并随后选择要调用的正确方法。这两个过程通常分别称为动态类型和动态绑定。