繼承總要有個來源,在Objective-C 中, NSObject 是所有的類別的源頭,所以時常可以看到
@interface ClassA : NSObject
................
@end
self, super
-(id)init
{
self = [super init];
if(self) {
// Initialize code here
}
return self;
}
在建構子中,我們常常這樣寫,self 表示自己,super則是父類別,而這段程式是先使用父類別的建構子,如果生成成功,進行子類別的初始化工作,最後回傳。
@class
在類別中要使用別的類別,通常我們都在.h檔中去import另一個類別的標頭檔,
#import "ClassB.h" // ClassA.h
也可以使用@class這個關鍵字去告訴complier,會更有效率的多
@class ClassB // ClassA.h
這裡會用到ClassB這個類別,你不用知道它的內容是什麼,儘管編譯過就是了。但事情沒這麼簡單,如果在ClassA.m檔中,有用到ClassB的方法,這時候編譯器怎麼會知道ClassB中的方法內容,就會出現錯誤。
把ClassA.m 檔中匯入ClassB.h檔就可以解決這個問題
#import "ClassB.h" // ClassA.m
那為何不一開始就在ClassA.h中,直接import ClassB.h檔就好了呢,是啊!!這樣不是多此一舉嗎~~所以使用時機是當你不會用到另一個類別的方法時,用 @class節省編譯很多時間。
另外,有一種情況是非用不可,那就是 circular inclusions,
#import "ClassB.h" // ClassA.h
#import "ClassA.h" // ClassB.h
這裡就需要用到@class,就不會再編譯的階段一直無窮的交互import。下面的例子,因為都有用到對方的方法,所以在.m中都需要 import 對方的.h檔。
ClassA.h
#import <Foundation/Foundation.h>
@class ClassB;
@interface ClassA : NSObject
{
NSString *name;
ClassB *b;
}
-(NSString *)name;
-(NSString *)theNameOfB;
@end
ClassA.m
#import "ClassA.h"
#import "ClassB.h"
@implementation ClassA
-(id)init
{
self = [super init];
if (self) {
name = @"A";
}
return self;
}
-(NSString *)name
{
return name;
}
-(NSString *)theNameOfB
{
if (!b) {
b = [[ClassB alloc]init];
}
return b.name;
}
@end
ClassB.h
#import <Foundation/Foundation.h>
@class ClassA;
@interface ClassB : NSObject
{
ClassA *a;
NSString *name;
}
-(NSString *)name;
-(NSString *)theNameOfA;
@end
ClassB.m
#import "ClassB.h"
#import "ClassA.h"
@implementation ClassB
-(id)init
{
self = [super init];
if (self) {
name = @"B";
}
return self;
}
-(NSString *)name
{
return name;
}
-(NSString *)theNameOfA
{
if (!a) {
a = [[ClassA alloc]init];
}
return a.name;
}
@end
main.m
#import <Foundation/Foundation.h>
#import "ClassA.h"
#import "ClassB.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
ClassA *a = [[ClassA alloc]init];
NSLog(@"ClassA use classB method, the name of ClassB : %@",[a theNameOfB]);
ClassB *b = [[ClassB alloc]init];
NSLog(@"ClassB use classA method, the name of ClassA : %@",[b theNameOfA]);
}
return 0;
}
輸出結果