Использование констант в абстрактных классах Objective-C? - PullRequest
2 голосов
/ 04 февраля 2012

Прежде всего, позвольте мне уточнить, что я знаю, что у вас не может быть реальных абстрактных классов в Objective-C. Когда я говорю абстрактный, я имею в виду, что я не создаю никаких экземпляров класса, а просто использую его как базовый класс для наследования.

Мой абстрактный класс содержит NSInteger. Все классы, унаследованные от этого абстрактного класса, должны будут использовать это целое число. После установки NSInteger никогда не будет изменен. Однако значение NSInteger будет зависеть от производного класса. Поскольку он никогда не будет изменен, я хочу сделать переменную const. Дело в том, что, если я сделаю это const, мне придется установить значение при создании экземпляра. Поэтому мне нужно было бы установить значение в базовом абстрактном классе - однако тогда я не могу отрегулировать значение на основе производного класса, в котором он существует.

Я понимаю, что это трудно понять, поэтому я создал некоторый базовый псевдокод. Я использовал NSString в качестве примера, но в моей программе это NSInteger:

Class animal: const NSString soundItMakes = "Sound" //the constant integer
//since soundItMakes is const I have to set it upon instantiation even though it doesn't make sense in the base class

Class dog: animal //derives from animal. Needs to change the const soundItMakes to fit a dog however since it was already set in animal, the base class, I can't really change it

Class cat: animal //derives from animal. Needs to change the const soundItMakes to fit cat however since it was already set in animal, the base class, I can't really change it.

Я не хочу удалять переменную из базового класса и вместо этого помещать ее в каждый производный класс, и при этом я не хочу делать ее непостоянной. Кто-нибудь видит решение этой проблемы? Я понимаю, что это сбивает с толку, поэтому, если требуется дополнительная информация, не стесняйтесь спрашивать.

Я использую Какао в Xcode 3.2.6 в Mac OS X Snowleopard.

Ответы [ 3 ]

5 голосов
/ 04 февраля 2012

Обычно я обращаюсь к этому методу, а не к ивару.

@interface Animal : NSObject
+ (NSString *)soundItMakes;
@end

@implementation Animal
+ (NSString *)soundItMakes {
  NSAssert(NO, @"Abstract");
}
@end

@implementation Dog
+ (NSString *)soundItMakes {
  return @"bark";
}
3 голосов
/ 04 февраля 2012

Первое: в этом случае я могу просто использовать протокол Animal.

Второе: если вам действительно нужна переменная для класса, вот один из подходов (который вы можете адаптировать для используемой версии компилятора):

@interface MONAnimal : NSObject
{
@private
  int animalCode;
  NSString * soundItMakes;
}

// designated initializer -- treat as protected
- (id)initWithAnimalCode:(int)inAnimalCode soundItMakes:(NSString *)soundItMakes;

... just don't declare setters for animalCode or soundItMakes!

@end

Тогда вы скажете:

@interface MONMoonBear : MONAnimal
@end

@implementation MONMoonBear

- (id)init
{
  return [super initWithAnimalCode:MONAnimalCode_MoonBear soundItMakes:@"Eating Garlic and Berries"];
}

@end

Есть еще несколько пробелов, которые нужно заполнить, но это толчок в направлении одного подхода.

1 голос
/ 04 февраля 2012

Сделать soundItMakes методом или @property(readonly), который переопределяется в дочерних классах.У вас нет выбора, кроме как переопределить в каждом классе, если значение в любом случае отличается для каждого класса.

// Animal.h
@interface Animal : NSObject
- (NSString *)soundItMakes;
@end

// Animal.m 
@implementation Animal
- (NSString *)soundItMakes
{
    // Throw exception, assert, etc.
    // This will force you to implement the subclass
    return (nil);
}

// Cat.h
@interface Cat : Animal
@property(readonly) NSString *soundItMakes;
@end

// Cat.m
@implementation Cat
@synthesize soundItMakes = _soundItMakes;

- (Cat *)init {
   NSString * const soundMade = @"Meow";

    self = [super init];
    if (self != nil)
        _soundItMakes = soundMade;
    return (self);
}
@end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...