复合(composition):将多个对象联系在一起以完成想要的功能。
在oc中,复合式通过包含作为实例变量的对象指针实现的。
@interface Unicyle : NSObject
{
Pedal *pedal;
Tire *tire;
}
@end //Unicyle
存取(accessor)方法是用来存取或改变某个对象属性的方法。如果要对其他对象中的属性进行操作,应该尽量使用对象提供的存取方法,绝对不能直接改变对象里面的值。那是不安全的,其实就是set和get。
- (void) setFire: (Tire*) tire atIndex: (int) index;
/*这里的方法名称是 setFire:atIndex:,方法名分段是为了对参数有更好的描述,比如C++中的一个方法IsRight(int. bool),在进行调用时IsRight(10, false),这样很难判断每个参数有什么具体含义,所以oc中会把每个参数都再方法中描述进去,这样更容易理解。这里的方法在调用的时候会是这个样子的[car setFire:tire atIndex:i],这样参数的意义就比较好理解了*/
在oc中所有对象间的交互都是通过指针实现的。
“Cannot find interface declaration for Tire”(无法找到Tire类的接口定义)之类的错误信息,通常是因为你忘记了用#import导入该类的头文件了。
通常,每个类都有两个文件:包含类@interface部分的头文件和包含@implementation部分的m文件。类的使用者可以通过#import命令导入头文件来获取该类的功能。
使用@class指令告诉编译器这是一个类。
利用OC的动态运行时分配机制,可以为现有的类添加新方法,在OC中被称为类别(category)。
程序员总是习惯把类别代码放在独立的文件中,通常会以“类名称+类别名称”的风格命名。
可以在类别中添加属性,但是不能添加实例变量,而且属性必须是@dynamic类型的。添加属性的好处在于可以通过点表达式来访问setter和getter方法。
类别有两个局限性。第一是无法向类中添加新的实例变量。类别没有空间容纳实例变量。第二就是名称冲突,类别中的方法与现有的方法重名。当发生名称冲突时,类别具有更高的优先级。类别方法将完全取代初始方法,导致初始方法不再可用。在自己的类别方法名中添加一个前缀,以确保不会发生名称冲突。
在Cocoa中,类别主要有3个用途:将类的实现代码分散到多个不同文件或框架中,创建对私有方法的前向引用,以及向对象添加非正式(informal protocol)。
如果想将大型的单个类分散到多个不同的.m文件中,可以使用类别。
类别还可以将方法分散到逻辑群组中,使编程人员可以更加容易地阅读头文件。