2012-03-25 26 views
0

super關鍵字告訴編譯器在首先定義方法的類的超類中搜索方法。例如,如果類父定義了一個包含[super init]的名爲X的新方法,那麼我在類Son中使用方法X,編譯器將在類祖父中搜索init方法,因爲X首先在類父中定義。超級總是在Objective-C中達到NSobject類嗎?

我的問題是,如果存在一個沒有改變的NSObject的繼承方法呢?例如,如果我在包含super的子類中使用「init」方法會發生什麼?由於在這種情況下,init方法首先在NSObject自身中定義。會「跳過」NSObject,或者只是實現NSObject內的任何內容,因爲沒有更高級的類?

-(id)init 
{   
    self=[super init]; 
    //code continues 
} 

回答

2

super是什麼意思是Objective-C調用self對象上的方法,但沒有在調用super的同一類中使用該方法的實現。稍顯混亂,但考慮:

@interface Grandparent : NSObject 
- (void)a; 
- (void)b; 
@end 

@implementation Grandparent 
- (void)a {NSLog(@"Grandparent a");} 
- (void)b {NSLog(@"Grandparent b");} 
@end 

@interface Parent : Grandparent 
@end 

@implementation Parent 
- (void)a {NSLog(@"Parent a"); [super a];} 
@end 

@interface Offspring : Parent 
- (void)a {NSLog(@"Offspring a"); [super a];} 
- (void)b {NSLog(@"Offspring b"); [super b];} 
@end 

看的-[Offspring b]實施。它稱爲[super b],但Parent未提供-b的實現。 Objective-C將繼續查找層次結構,直到找到-[Grandparent b]並執行它。如果Grandparent沒有該方法,它將在NSObject上看起來。

現在考慮致電-[Offspring a]。這會記錄一條消息,然後調用[super a],這是Parent上的實現。該消息又調用[super a],因爲它使用在Parent上定義的方法來執行此操作,所以這將開始尋找-[Grandparent a](即使實例實際上是Offspring對象)。

這一切都意味着,對於任何NSObject後代,通過super調用消息有在NSObject實施方法結束了的可能性。這與說super總是達到NSObject是不一樣的,因爲Objective-C中存在不是從NSObject(如NSProxy)派生的類。

+0

我再次在Xcode中進行了一些調整,看起來「超級」可以繞過明確實施的方法。例如,如果Parent定義並實現了一個新的方法「c」,並且執行[super a],並且如果你在main.m中執行[offspring1 c],那麼super將在Parent中繞過「a」並檢查祖父母中的「a」 ,即使Parent是後代的第一個超類。所以我猜顯式實現是使用「超級」的關鍵? – Rexroth 2012-03-25 17:44:37

+1

@Rexroth正如我所說的,它從定義方法的類的超類開始。您的'c'方法在'Parent'上定義,因此'super'解析將以'祖父母'開頭。 – 2012-03-25 17:47:03

+0

因此,如果我在子代中再次定義「c」,即使代碼完全相同,它也會被視爲重寫或「重新定義」。因爲如果我要在後代的@implementation中顯式實現「c」,那麼它開始於類Parent,它是類「c」被重新定義的超類。 – Rexroth 2012-03-25 18:29:44

1

你是對的。假設父親和祖父都不會覆蓋init,但是Son會使用您的代碼段中的實現。如果您的電子郵件地址爲[[aSon alloc] init],那麼致電[super init]會尋找祖父實施的init,這將不會被發現,然後它會轉到NSObject的實施,然後執行。

+0

'super'不會**看實際對象的類。 – 2012-03-25 18:40:03

+0

刪除違規行爲。 – yuji 2012-03-25 19:06:43

+0

downvote刪除。 – 2012-03-26 06:35:30