子类继承类工厂方法的问题(Objective-C)

时间:2014-02-13 01:43:06

标签: objective-c

虽然我对C#非常熟悉,但我在Objective C和iOS开发方面还是全新的。所以我正在学习这门语言。我不明白的是为什么以下代码会引发编译器错误(是的,这是来自Programming with Objective C的练习:

SNDPerson:

@interface SNDPerson : NSObject

@property NSString *first;
@property NSString *last;

+ (SNDPerson *)person;
@end

@implementation SNDPerson
+ (SNDPerson *)person
{
   SNDPerson *retVal = [[self alloc] init];
   retVal.first = @"Ari";
   retVal.last = @"Roth";

   return retVal;
}
@end

SNDShoutingPerson:

#import "SNDPerson.h"

@interface SNDShoutingPerson : SNDPerson
@end

@implementation SNDShoutingPerson

// Implementation is irrelevant here; all it does is override a method that prints a string
// in all caps.  This works; I've tested it.  However, if necessary I can provide more code.
// The goal here was for a concise repro.

@end

主要方法:

- int main(int argc, const char * argv[])
{
   SNDShoutingPerson *person = [[SNDShoutingPerson alloc] person];  // Error
   ...
}

错误是“没有可见的@interface for”SNDShoutingPerson“声明选择器”person“。

不应该这样吗? SNDShoutingPerson继承自SNDPerson,所以我认为它可以访问SNDPerson的类工厂方法。我在这里做错了什么,还是我必须在SNDShoutingPerson的界面上声明方法?练习文本暗示我所做的应该是Just Work。

3 个答案:

答案 0 :(得分:3)

调用类方法时忽略+alloc

SNDShoutingPerson *person = [SNDShoutingPerson person];

简言之:

+ (id)foo表示类方法。采用以下形式:

[MONObject method];

- (id)foo表示实例方法。采用以下形式:

MONObject * object = ...; // << instance required
[object method];

此外,您可以在这种情况下声明+ (instancetype)person,而不是+ (SNDPerson *)person;

答案 1 :(得分:0)

更改行SNDShoutingPerson *person = [[SNDShoutingPerson alloc] person]; //错误

SNDShoutingPerson *person = [[SNDShoutingPerson alloc] init]; 

干杯。

如果你想调用类方法:

SNDPerson person = [SNDPerson person];

答案 2 :(得分:0)

person是一个类方法,但是你试图用alloc返回的不完整构造的实例来调用它。杀死alloc并执行[SNDShoutingPerson person]

顺便说一句,这与子类无关。如果你写了[[SNDPerson alloc] person],你会得到同样的错误。