下面的代码是伪代码。 想象一下“水果”这一类,它有一种工厂方法来制作水果。
interface Fruit
{
}
+(Fruit*) createFruit:
{
return [[Fruit alloc] init autorelease];
}
现在我想将Fruit子类化为Apple:
interface Apple : Fruit
{
int iSeeds;
}
+(Apple*) createAppleWithColor: (int) iSeeds
{
Apple* oApple = [Apple createFruit:];
oApple.iSeeds = iSeeds;
return oApple;
}
问题:
勒
答案 0 :(得分:1)
一些事情。
您的createFruit方法错误。它应该是:
+ (Fruit *) createFruit { //autorelease, because the Create Rule only applies to CoreFoundation functions return [[[Fruit alloc] init] autorelease]; }
默认情况下,实例变量为@protected
。这意味着它们可以由类和任何子类直接访问。您可以将其设为@protected
,@private
,@public
和@package
。你这样做:
@interface Apple : Fruit { @private int iSeed } ... @end
如果您希望实例变量是只读的,则不要将其声明为@public
,而是为其创建一个getter。例如:
- (int) iSeeds { return iSeeds; }
但是,由于实例变量是readonly,因此无法在外部进行设置。解决这个问题的方法是在初始化期间给Apple一个iSeed值:
- (id) initWithSeeds:(int)aniSeedValue { if (self = [super init]) { iSeed = aniSeedValue; } return self; }
然后将createAppleWithColor:(int)iSeeds
方法设为:
+ (Fruit *) createAppleWithColor:(int)iSeeds { return [[[Apple alloc] initWithSeeds:iSeeds] autorelease]; }
答案 1 :(得分:1)
还有一件事。如果你有一个适用于类及其子类的工厂方法,你可以(可能应该)这样做:
+(Fruit*) fruit
{
[[[self alloc] init] autorelease];
}
这意味着如果您使用子类调用该方法,您将获得一个正确类型的对象,例如。
Fruit* apple = [Apple fruit];
当然,您需要为Apple提供一个init方法,为iSeeds提供合适的默认值,然后调用-initWithSeeds: