通常在Objective-C中爲每個類創建一個指定的初始化程序,然後子類使用相同的初始化程序。因此,不是使用initAnimal和initDog,而是使用init。然後狗子類會定義自己的init方法,並調用指定的初始化其父類:
@implementation Dog
-(id)init
{
if((self = [super init])) { // call init in Animal and assign to self
// do something specific to a dog
}
return self;
}
@end
你真的沒有指定initDog和initAnimal因爲類是對的右側聲明分配...
更新:我加入了以下的答案,以反映問題的其他信息
有許多的方法,以確保子不叫比其他初始化他們指定的初始化程序和你最終的方式ely選擇將主要基於您的整個設計。 Objective-C的好處之一是它非常靈活。我會在這裏給你兩個例子讓你開始。首先,如果您創建的子類具有與其父類不同的指定初始值設定項,您可以重載父項的初始值設定項並引發異常。這會讓程序員立即知道他們已經違反了班級的協議......但是,應該說你應該有一個很好的理由來做這件事,並且應該有很好的文件證明子類可能會不要使用與超類相同的初始值設定項。
@implementation Dog
-(id)init
{
// Dog does not respond to this initializer
NSAssert(false, @"Dog classes must use one of the designated initializers; see the documentation for more information.");
[self autorelease];
return nil;
}
-(id)initWithFur:(FurOptionsType)furOptions
{
if((self = [super init])) {
// do stuff and set up the fur based on the options
}
return self;
}
@end
另一種方法是讓初始化器更像你的原始示例。在這種情況下,您可以更改父類的默認初始值以始終失敗。然後您可以爲您的父類創建一個私有初始化器,然後確保每個人都在子類中調用適當的初始化器。這種情況顯然比較複雜:
@interface Animal : NSObject
-(id)initAnimal;
@end
@interface Animal()
-(id)_prvInitAnimal;
@end
@interface Dog : Animal
-(id)initDog;
@end
@implementation Animal
-(id)init
{
NSAssert(false, @"Objects must call designated initializers; see documentation for details.");
[self autorelease];
return nil;
}
-(id)initAnimal
{
NSAssert([self isMemberOfClass:[Animal class]], @"Only Animal may call initAnimal");
// core animal initialization done in private initializer
return [self _prvInitAnimal];
}
-(id)_prvInitAnimal
{
if((self = [super init])) {
// do standard animal initialization
}
return self;
}
@end
@implementation Dog
-(id)initDog
{
if((self = [super _prvInitAnimal])) {
// do some dog related stuff
}
return self;
}
@end
在這裏您會看到Animal and Dog類的接口和實現。 Animal是指定的頂層對象,因此覆蓋NSObject的init實現。任何在動物或動物的任何子類上調用init的人都會得到一個斷言錯誤,將其引用到文檔中。 Animal還定義了私人類別上的私人初始值設定項。私有類將留在你的代碼中,當它們調用super時,Animal的子類將調用這個私有的初始化方法。它的目的是調用Animal的超類(在這種情況下爲NSObject)上的init,並執行可能必需的任何通用初始化。
最後,在動物的initAnimal方法的第一行是斷言,接收器實際上是一個動物,而不是一些子類。如果接收器不是動物,則程序將失敗並出現斷言錯誤,程序員將被引用到文檔中。
這些只是你如何設計一些符合你的特定要求的兩個例子。但是,我會強烈建議你考慮你的設計約束,看看你是否真的需要這種設計,因爲它在可可和大多數OO設計框架中都是非標準的。例如,你可以考慮製作各種動物根級對象,而只需要動物協議,要求所有各種「動物」對某些動物通用消息作出響應。這樣,每隻動物(和動物的真正的亞類)都可以自己處理它們的指定初始化子,並且不必依賴以這種特定的非標準方式行事的超類。
好Zoul,我所做的更新基於更新你的問題我的答案......這是相當長的了,但我希望它給你一些你要找的洞察力。 – 2008-11-11 08:24:36
因爲這是最好的結果。現代XCode中的答案可以通過NS_UNAVAILABLE實現。請參閱:http://stackoverflow.com/questions/195078/is-it-possible-to-make-the-init-method-private-in-objective-c#answer-27693034 – m4js7er 2016-03-17 16:20:57