Code below is pseudo code.
Imagine a class “Fruit” which has a factory method to create a fruit.
interface Fruit
{
}
+(Fruit*) createFruit:
{
return [[Fruit alloc] init autorelease];
}
Now I want to subclass the Fruit to get an Apple:
interface Apple : Fruit
{
int iSeeds;
}
+(Apple*) createAppleWithColor: (int) iSeeds
{
Apple* oApple = [Apple createFruit:];
oApple.iSeeds = iSeeds;
return oApple;
}
Questions:
- How can I make “iSeeds” private so it cannot be changed from outside? If I add a “private” keyword it does not build anymore.
- Still I want to set iSeeds from inside my Apple’s factory method.
- I want users allow to READ the content of iSeeds. So I suppose I should have a getter but I can’t get it to work. I always get some error about “LValue assignment”.
- The Fruit’s createFruit is making use of autorelease. Does the Apple have to reatin/release anything?
René
A couple things.
Your createFruit method is wrong. It should be:
+ (Fruit *) createFruit { //autorelease, because the Create Rule only applies to CoreFoundation functions return [[[Fruit alloc] init] autorelease]; }Instance variables are
@protectedby default. That means they can be directly accessed by the class and any subclasses. You can make it@protected,@private,@public, and@package. You do so like this:@interface Apple : Fruit { @private int iSeed } ... @endIf you want an instance variable to be readonly, then don’t declare it as
@public, but make a getter for it. For example:- (int) iSeeds { return iSeeds; }However, since the instance variable is readonly, you can’t set it externally. The way around this is to give the Apple a iSeed value during initialization:
- (id) initWithSeeds:(int)aniSeedValue { if (self = [super init]) { iSeed = aniSeedValue; } return self; }Then make your
createAppleWithColor:(int)iSeedsmethod like:+ (Fruit *) createAppleWithColor:(int)iSeeds { return [[[Apple alloc] initWithSeeds:iSeeds] autorelease]; }Finally, you should read the Naming Conventions guide and the Memory Management guide.