首先,让我澄清一下,我知道你不能在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.
我不想从基类中删除变量,而是将它放在每个派生类中,也不想让它变为非常量。有没有人看到这个解决方案?我意识到这是令人困惑的,所以如果需要更多信息,请随时询问。
我在Mac OS X Snowleopard中使用Xcode 3.2.6中的Cocoa。
答案 0 :(得分:5)
通常我会用方法而不是ivar来解决这个问题。
@interface Animal : NSObject
+ (NSString *)soundItMakes;
@end
@implementation Animal
+ (NSString *)soundItMakes {
NSAssert(NO, @"Abstract");
}
@end
@implementation Dog
+ (NSString *)soundItMakes {
return @"bark";
}
答案 1 :(得分:3)
首先:在这种情况下,我可能只使用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
还有一些空白要填补 - 但这是推动一种方法的方向。
答案 2 :(得分:1)
使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