イニシャライザ内からオーバーライドを呼び出そうとしても、うまくいきません。その理由は簡単に理解できます。オーバーライドはサブクラスに属し、サブクラスの初期化を開始する前にスーパークラス インスタンスの初期化を完了する必要があるため、派生メソッドを呼び出すと、「通常の" メソッドが呼び出され、インスタンスの初期化が完了しました。一般に、Java または C# のコンストラクターからバーチャルを呼び出すことは、まったく同じ理由で、お勧めできません。C++ では、コンストラクターから virtual を呼び出すと、コンストラクター自身のクラスの実装にリダイレクトされます (つまり、Objective C で見られるのと同じことです)。
静的メソッドのオーバーライドが許可されていない C# や Java とは異なり、Objective C では、クラス メソッドのクラス固有の実装を提供できます。このメカニズムを使用して、目的を達成できます。次のように、派生クラスでクラス メソッドを定義し、それを基本クラスから呼び出します。
@interface TT : NSObject
-(id)init;
@end
@interface Test1 : TT
+(void)doit;
@end
@interface Test2 : TT
+(void)doit;
@end
@implementation Test1
+(void) doit {
NSLog(@"Test1");
}
@end
@implementation Test2
+(void) doit {
NSLog(@"Test2");
}
@end
@implementation TT
-(id) init {
if (self=[super init]) {
// The "magic" is in the following line:
[self->isa doit];
}
return self;
}
@end
電話すると
[[Test1 alloc] init];
[[Test2 alloc] init];
分かりますか
Test1
Test2
ログで。