3

C#/Java プログラマーとして、次の問題を解決するのに苦労しています。

基本クラス「B」があります。その init メソッドでは、メソッド「SetupStuff」を呼び出します。基本クラスの場合、このメソッドは空です。

次に、「B」を継承する派生クラス「D」があります。D もメソッド "SetupStuff" を実装しています (実際にそこで何かを行います)。

問題は、D のオブジェクトを作成するときに、その「SetupStuff」が呼び出されないことです。B の init メソッドが呼び出され、次に の空の「SetupStuff」が呼び出されます。

派生クラスのメソッドを呼び出すにはどうすればよいですか?

4

3 に答える 3

2

イニシャライザ内からオーバーライドを呼び出そうとしても、うまくいきません。その理由は簡単に理解できます。オーバーライドはサブクラスに属し、サブクラスの初期化を開始する前にスーパークラス インスタンスの初期化を完了する必要があるため、派生メソッドを呼び出すと、「通常の" メソッドが呼び出され、インスタンスの初期化が完了しました。一般に、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

ログで。

于 2012-07-13T16:39:17.647 に答える
0

Objective-c のすべてのメソッドは、デフォルトで仮想です。したがって、派生クラスでオーバーライドするメソッドを実装するだけです。親メソッドを呼び出して、何も見逃していないことを確認することを忘れないでください

そして、B ではなく D クラスのインスタンスを作成するようにしてください。

[[D alloc] init];

次に、オーバーライドされたメソッドを適切に呼び出す必要があります

于 2012-07-13T16:02:35.557 に答える
0

子メソッドを次のように初期化するのを忘れましたか?

-(void) SetupStuff{ // This is the child class implementation
[super SetupStuff];
}

Objective-C では、既存のメソッドを上書きしている場合でも、親メソッドを手動で呼び出す必要があります。

于 2012-07-13T16:04:10.200 に答える