【问题标题】:"virtual" method's return type in objective-cObjective-c 中“虚拟”方法的返回类型
【发布时间】:2011-10-14 03:30:35
【问题描述】:

我有一个应该是抽象的类。在其中一个抽象方法中,返回类型可能是 class1、class2 或 class3 的实例,具体取决于实现该方法的类。我想知道我应该如何在抽象类中声明该方法。我考虑过使用动态类型,但我希望将返回类型限制为 3 个类之一,而不是每种类型,此外我不确定我是否可以覆盖它,以便在继承类中返回类型不会匹配抽象类中的返回类型。

如果你能帮我解决这个问题,我会很高兴,
天呐!

【问题讨论】:

  • 难道你想要的类似于类集群?更多信息:developer.apple.com/library/mac/#documentation/General/…
  • 可能是,但我看不出这如何解决我的问题,因为我的问题仅与特定方法有关,而不与整个班级有关...
  • 因为类集群的 init-methods 做一些非常相似的事情——你调用一个 init 方法,类根据内部规则给你一个特定类的实例。但这只是灵感的输入。

标签: objective-c dynamic virtual abstract typing


【解决方案1】:

看看这个:

#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 发送到myBA 返回B)和协变,这似乎是您想要的。

请注意,您也可以这样做:

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

但这会返回一个A,并且向它发送foo 会告诉您该类没有响应选择器#foo。如果你省略了 (B*) 演员表,你会在编译时收到一个警告。

但是 ISTM 认为协方差在 Objective-C 中不是什么大问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-22
    • 2013-05-29
    • 1970-01-01
    • 2012-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多