object-c學習(三)源文件分割與組織

如何進行源文件的組織
代碼中的類在定義中自然的拆分成接口和實現兩個部分,一個.h文件存放接口部分的代碼:類的@interface指令,公共的struct定義,enum常量,#define
和extern全局變量。頭文件名與類名一致,只是後綴爲.h。
所有的實現細節(類的@implementation,全局變量的定義,私有struct等)都放在與類同名,以.m爲擴展名的文件中。

將上面的car程序使用這樣的原則拆分爲:car.h,car.m;Tire.h,Tire.m;Engine.h,Engine.m;car_split.m.

Tire.h:

#import <Cocoa/Cocoa.h>

@interface Tire : NSObject
@end // Tire

其中Cocoa.h包含了Foundation.h以及其他的一些東西。

Tire.m:

#import "Tire.h"


@implementation Tire

- (NSString *) description
{
    return (@"I am a tire. ");
} // description

@end // Tire

這裏面只有一個描述的方法。頭文件包含“Tire.h”

Engine.h:

#import <Cocoa/Cocoa.h>

@interface Engine : NSObject
@end // Engine

Engine.m:

#import "Engine.h"

@implementation Engine

- (NSString *) description
{
    return (@"I am an engine!");
} // description

@end // Engine

Car.h:

#import <Cocoa/Cocoa.h>

@class Tire;
@class Engine;

@interface Car : NSObject
{
    Tire *tires[4];
    Engine *engine;
}

- (void) setEngine: (Engine *) newEngine;

- (Engine *) engine;


- (void) setTire: (Tire *) tire
         atIndex: (int) index;

- (Tire *) tireAtIndex: (int) index;

- (void) print;

@end // Car

如果沒有@class Tire;@class Engine;那麼程序編譯時候會出錯,因爲在car接口聲明中用到了Tire和Engine類,在沒有互相引用的前提下,一種解決辦法是#import兩個.h頭文件,這樣會引入很多信息,另一種是使用@class方式,因爲它只是通過指針引用了Tire和Engine。@class創建了一個前向引用,就是在告訴編譯器:相信我,以後你會知道這個類到底是什麼,但是現在,你知道需要知道這些。

如果有循環依賴的關係,即A類使用B類,B類也使用A類。如果試圖使用#import語句讓這兩個類相互引用,那麼就會出現編譯錯誤,但是如果在A.h使用@class B,B.h中使用@class A ,那麼就可以了。巧妙使用@class指令能夠減少編譯時間。

car.m:

#import "Car.h"
#import "Engine.h"
#import "Tire.h"

@implementation Car

- (id) init
{
    if (self = [super init]) {
        engine = [Engine new];

        tires[0] = [Tire new];
        tires[1] = [Tire new];
        tires[2] = [Tire new];
        tires[3] = [Tire new];
    }

    return (self);

} // init


- (Engine *) engine
{
    return (engine);
} // engine


- (void) setEngine: (Engine *) newEngine
{
    engine = newEngine;
} // setEngine


- (void) setTire: (Tire *) tire
         atIndex: (int) index
{
    if (index < 0 || index > 3) {
        NSLog (@"bad index (%d) in setTire:atIndex:",
               index);
        exit (1);
    }

    tires[index] = tire;

} // setTire:atIndex:


- (Tire *) tireAtIndex: (int) index
{
    if (index < 0 || index > 3) {
        NSLog (@"bad index (%d) in tireAtIndex:",
               index);
        exit (1);
    }

    return (tires[index]);

} // tireAtIndex:



- (void) print
{
    NSLog (@"%@", engine);

    NSLog (@"%@", tires[0]);
    NSLog (@"%@", tires[1]);
    NSLog (@"%@", tires[2]);
    NSLog (@"%@", tires[3]);

} // print

@end // Car
最後的主程序:

#import <Foundation/Foundation.h>


#import "Car.h"
#import "Tire.h"
#import "Engine.h"


int main (int argc, const char * argv[]) 
{
	Car *car = [Car new];
	
	int i;
	for (i = 0; i < 4; i++) {
		Tire *tire = [Tire new];
		
		[car setTire: tire
			 atIndex: i];
	}
	
	Engine *engine = [Engine new];
	[car setEngine: engine];
	
	[car print];
	
	return (0);
	
} // main




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章