繼承和複合,是類與類之間兩種重要的關係。接下來,我們就借用書本上的例子來介紹下複合關係。
假如我們要構建一個簡單的汽車模型,那麼要有一個發動機(Engine)和四個輪子(Tire)。基本定義的代碼如下:
首先,先定義和簡單的實現Tire類。
<span style="font-size:12px;">@interface Tire : NSObject
@end //Tire
@implementation Tire
-(NSString *) description{
return (@"I am a tire. I last a while.");
}
@end</span>
在實現方法中的description沒有定義,那麼他是哪裏來的呢?在Cocoa中,NSLog()可以使用%@格式說明符來輸出對象,NSLog()將對象發送了description消息,然後對象的description方法生成一個NSString並將其返回。所以,在類中提供description方法,就可以自定義NSLog()。
然後定義和簡單的實現Engine類。
<span style="font-size:12px;"> @interface Engine : NSObject
@end
@implementation Engine
-(NSString *) description {
return (@"I am an engine. Vroom!");
}
@end</span>
然後定義汽車(Car)類本身。
在實現Car類的代碼中,我們定義了一個類型爲id的init的方法。這裏的作用是:初始化實例變量,創建1個engine變量和4個tire變量。使用new創建新對象的時候,系統會自動給對象分配內存,然後自動調用init方法,使該對象進入可以使用的狀態。
關於init方法中,if語句:if(self = [super init]),這個條件是什麼意思呢?爲了讓超類(在這裏是指:NSObject)將所有需要的初始化工作一次性完成。需要調用[super init]。init方法的返回值(id類型數據,即泛型對象指針)就是被初始化的對象。而將返回的結果賦值給self則是Objective-c的慣例。這樣做是爲了防止超類在初始化過程中返回的對象與一開始創建的不一致。
最後在main主函數中,創建一個Car對象,然後調用drive方法,代碼如下:
<span style="font-size:12px;"> int main(int argc, const char * argv[])
{
Car *car;
car = [Car new];
[car drive];
return 0;
}</span>
運行效果: