2

私は抽象的であるはずのクラスを持っています。その抽象メソッドの 1 つで、戻り値の型は、メソッドを実装しているクラスに応じて、class1、class2、または class3 のインスタンスになる場合があります。抽象クラスでメソッドをどのように宣言すればよいのでしょうか。動的型付けを使用することを考えましたが、戻り値の型をすべての型ではなく 3 つのクラスのいずれかに制限する必要があり、さらに継承クラスで戻り値の型が変更されないようにオーバーライドできるかどうかもわかりません。抽象クラスの戻り値の型と一致します。


Tnxさん、手伝ってくれたら嬉しいです!

4

1 に答える 1

3

これを見てください:

#import <Foundation/Foundation.h>

@interface A : NSObject { }
- (A*) newItem;
- (void) hello;
@end

@interface B : A { int filler; }
- (B*) newItem;
- (void) hello;
- (void) foo;
@end

@implementation A
- (A*) newItem { NSLog(@"A newItem"); return self; }
- (void) hello { NSLog(@"hello from A"); }
@end

@implementation B
- (B*) newItem { NSLog(@"B newItem"); return self; }
- (void) hello { NSLog(@"hello from B: %d", filler); }
- (void) foo { NSLog(@"foo!"); }
@end

int main (int argc, const char * argv[])
{

    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    A *origA = [A new];
    A *myA = [origA newItem];

    NSLog(@"myA: %@", myA);

    B *origB = [B new];
    B *myB = [origB newItem];
    A *myBA = [origB newItem];

    NSLog(@"myB: %@\nmyBA: %@", myB, myBA);

    [origA hello];
    [origB hello];
    [myA hello];
    [myB hello];
    [myBA hello];

    NSLog(@"Covariance?");

    [pool drain];
    return 0;
}

これはかなり圧縮された構文であり、メモリ管理はうまくいきませんが、それnewItemが仮想的 ( に送信newItemするとa がmyBA返されるB) であり、共変であることがわかります。

次のこともできることに注意してください。

    B *myAB = (B*)[origA newItem];

しかし、それはを返し、Aそれに送信fooすると、クラスがセレクターに応答しないことがわかり#fooます。キャストを省略した場合(B*)、コンパイル時にこれに関する警告が表示されます。

しかし、Objective-C では、ISTM の共分散は大きな問題ではありません。

于 2011-07-27T11:23:09.917 に答える