Основы Objective-C: подклассы и доступность переменных-членов - PullRequest
1 голос
/ 19 мая 2010

Код ниже является псевдокодом. Представьте себе класс «Фрукты», в котором есть фабричный метод создания фруктов.

interface Fruit
{
}
+(Fruit*) createFruit:
{
  return [[Fruit alloc] init autorelease];
}

Теперь я хочу создать подкласс Fruit, чтобы получить яблоко:

interface Apple : Fruit
{
int iSeeds;
}
+(Apple*) createAppleWithColor: (int) iSeeds
{
Apple* oApple = [Apple createFruit:];
oApple.iSeeds = iSeeds;
return oApple;
}

Вопросы:

  • Как я могу сделать iSeeds приватным, чтобы его нельзя было изменить извне? Если я добавлю ключевое слово "private", оно больше не будет создаваться.
  • Тем не менее, я хочу установить iSeeds из заводского метода моего Apple.
  • Я хочу, чтобы пользователи разрешали ПРОЧИТАТЬ содержание iSeeds. Так что я полагаю, у меня должен быть получатель, но я не могу заставить его работать. Я всегда получаю сообщение об ошибке «присваивание LValue».
  • Фрукты createFruit использует авто-релиз. Должен ли Apple что-либо переоценивать / выпускать?

Рене

Ответы [ 2 ]

1 голос
/ 19 мая 2010

Еще одна вещь. Если у вас есть метод фабрики, который применяется к классу и его подклассам, вы можете (вероятно, должны) сделать это:

+(Fruit*) fruit
{
    [[[self alloc] init] autorelease];
}

Это означает, что если вы вызовете метод с подклассом, вы получите объект правильного типа, например

Fruit* apple = [Apple fruit];

Конечно, вам нужно предоставить метод init для Apple, который предоставляет подходящее значение по умолчанию для iSeeds, а затем вызывает -initWithSeeds:

1 голос
/ 19 мая 2010

Пара вещей.

  1. Ваш метод createFruit неверен. Должно быть:

    + (Fruit *) createFruit {
      //autorelease, because the Create Rule only applies to CoreFoundation functions
      return [[[Fruit alloc] init] autorelease];
    }
  2. Переменные экземпляра по умолчанию @protected. Это означает, что они могут быть доступны непосредственно классу и любым подклассам. Вы можете сделать это @protected, @private, @public и @package. Вы делаете это так:

    @interface Apple : Fruit {
      @private
      int iSeed
    }
    ...
    @end
  3. Если вы хотите, чтобы переменная экземпляра была доступна только для чтения, не объявляйте ее как @public, а создайте для нее метод получения. Например:

    - (int) iSeeds {
      return iSeeds;
    }
  4. Однако, поскольку переменная экземпляра доступна только для чтения, вы не можете установить ее внешне. Способ обойти это - дать 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];
    }
  5. Наконец, вы должны прочитать руководство по именованию и Руководство по управлению памятью .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...