2010-06-08 119 views
1

我將創建一個基類,爲所有子類實現非常類似的功能。這是在different question中回答的。但是我現在需要知道的是如果/如何可以投入各種函數(在基類中)來返回子類對象。這既適用於給定的函數,也適用於函數調用。Objective-C的子類和基類鑄造

(我的方式與CoreData工作)

基類中的功能(這是與將要成爲我的子類)

+(Structure *)fetchStructureByID:(NSNumber *)structureID inContext:(NSManagedObjectContext *)managedObjectContext {...} 

而作爲一個給定函數中的函數調用:

Structure *newStructure = [Structure fetchStructureByID:[currentDictionary objectForKey:@"myId"]]; 
               inContext:managedObjectContext]; 

結構是我的一個子類,所以我需要重寫這兩種使他們「通用」,並可以應用到其他的亞型(誰正在調用該函數)。

我該怎麼做?

更新:我剛剛意識到,在第二部分實際上有兩個問題。您不能將[Structure fetch ...]更改爲[self fetch ...],因爲它是類方法,而不是實例方法。我該如何解決這個問題?

+1

構造函數/初始化方法通常返回'id'出於這個原因。 – rpetrich 2010-06-09 00:05:41

回答

2

如果我正確理解你的問題,我相信關鍵是[self class]成語。

只要您的更新要求調用當前類的類方法,您可以使用[self class]。如:

Structure *newStructure = [[self class] fetchStructureByID:[currentDictionary 
               objectForKey:@"myId"]]; 
               inContext:managedObjectContext]; 

編輯:我重做這每@ rpetrich的評論返回id - 更清潔,只要你確定你調用-createConfiguredObject實例的類型,避免了-isKindOfClass:的需要上。對於第一部分,您可以返回一個id(指向任何對象的指針)並記錄它將返回它所調用的同一類的實例。然後在代碼中,您需要在實例化方法中的新對象的任何地方使用[self class]。

例如

// Returns an instance of the same class as the instance it was called on. 
// This is true even if the method was declared in a base class. 
-(id) createConfiguredObject { 
    Structure *newObject = [[[self class] alloc] init]; 
    // When this method is called on a subclass newObject is actually 
    // an instance of that subclass 
    // Configure newObject 
    return newObject; 
} 

然後,您可以在代碼中使用此如下:

StructureSubclass *subclass = [[[StructureSubclass alloc] init] autorelease]; 
subclass.name = @"subclass"; 

// No need to cast or use isKindOfClass: here because returned object is of type id 
// and documented to return instance of the same type. 
StructureSubclass *configuredSubclass = [[subclass createConfiguredObject] autorelease]; 
configuredSubclass.name = @"configuredSubclass"; 

因爲如果你有一個-createConfiguredObject方法,它返回它被稱爲在同一類的一個實例,它將實現如下參考,我指的-isKindOfClass:和鑄造到適當的子類如下:

Structure *structure; 
// Do stuff 
// I believe structure is now pointing to an object of type StructureSubclass 
// and I want to call a method only present on StructureSubclass. 
if ([structure isKindOfClass:[StrucutreSubclass class]]) { 
    // It is indeed of type StructureSubclass (or a subclass of same) 
    // so cast the pointer to StructureSubclass * 
    StructureSubclass *subclass = (StructureSubclass *)structure; 
    // the name property is only available on StructureSubclass. 
    subclass.name = @"myname"; 
} else { 
    NSLog(@"structure was not an instance of StructureSubclass when it was expected it would be."); 
    // Handle error 
} 
+0

「在投射到適當的子類之前」是什麼意思? 到目前爲止,這對我有很大幫助,但我仍試圖解決一些問題。特別是當試圖設置一個變量像newObject.name = ...因爲結構(在你的情況下基類)沒有名稱,但子類。在那種情況下,我是否需要讓Structure看起來像它也有這些變量? – RyanJM 2010-06-08 21:35:44

+0

對不起,遲到的迴應。我花了一段時間來實現它。這真的很有幫助,謝謝。 – RyanJM 2010-06-23 22:32:34

+0

不客氣。我很高興這很有幫助。 – 2010-06-23 23:42:12