我最初是一名Java程序员,现在使用Objective-C。我想创建一个抽象类,但这在Objective-C中似乎不可能。这可能吗?

如果不是,在Objective-C中,我能有多接近抽象类?


当前回答

(更多相关的建议)

我想有一种方法让程序员知道“不要从子调用”,并完全覆盖(在我的情况下,仍然提供了一些默认功能,代表父时,未扩展):

typedef void override_void;
typedef id override_id;

@implementation myBaseClass

// some limited default behavior (undesired by subclasses)
- (override_void) doSomething;
- (override_id) makeSomeObject;

// some internally required default behavior
- (void) doesSomethingImportant;

@end

这样做的好处是程序员会看到声明中的“override”,并且知道他们不应该调用[super ..]。

当然,必须为此定义单独的返回类型是很难看的,但它可以作为一个足够好的视觉提示,并且您可以很容易地在子类定义中不使用“overrides”部分。

当然,当扩展是可选的时,类仍然可以有默认实现。但是,就像其他答案所说的那样,在适当的时候实现一个运行时异常,比如对于抽象(虚拟)类。

如果有像这样的内置编译器提示就好了,甚至提示什么时候最好预/后调用super的实现,而不是不得不挖掘注释/文档或…假设。

其他回答

(更多相关的建议)

我想有一种方法让程序员知道“不要从子调用”,并完全覆盖(在我的情况下,仍然提供了一些默认功能,代表父时,未扩展):

typedef void override_void;
typedef id override_id;

@implementation myBaseClass

// some limited default behavior (undesired by subclasses)
- (override_void) doSomething;
- (override_id) makeSomeObject;

// some internally required default behavior
- (void) doesSomethingImportant;

@end

这样做的好处是程序员会看到声明中的“override”,并且知道他们不应该调用[super ..]。

当然,必须为此定义单独的返回类型是很难看的,但它可以作为一个足够好的视觉提示,并且您可以很容易地在子类定义中不使用“overrides”部分。

当然,当扩展是可选的时,类仍然可以有默认实现。但是,就像其他答案所说的那样,在适当的时候实现一个运行时异常,比如对于抽象(虚拟)类。

如果有像这样的内置编译器提示就好了,甚至提示什么时候最好预/后调用super的实现,而不是不得不挖掘注释/文档或…假设。

与其尝试创建抽象基类,不如考虑使用协议(类似于Java接口)。这允许您定义一组方法,然后接受符合协议的所有对象并实现这些方法。例如,我可以定义一个操作协议,然后有一个这样的函数:

- (void)performOperation:(id<Operation>)op
{
   // do something with operation
}

其中op可以是任何实现Operation协议的对象。

如果您需要抽象基类做的不仅仅是定义方法,那么您可以创建一个常规的Objective-C类并防止它被实例化。只需重写- (id)init函数,并使其返回nil或assert(false)。这不是一个非常干净的解决方案,但由于Objective-C是完全动态的,所以实际上没有与抽象基类直接等价的东西。

Typically, Objective-C class are abstract by convention only—if the author documents a class as abstract, just don't use it without subclassing it. There is no compile-time enforcement that prevents instantiation of an abstract class, however. In fact, there is nothing to stop a user from providing implementations of abstract methods via a category (i.e. at runtime). You can force a user to at least override certain methods by raising an exception in those methods implementation in your abstract class:

[NSException raise:NSInternalInconsistencyException 
            format:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)];

如果您的方法返回一个值,那么使用起来会更容易一些

@throw [NSException exceptionWithName:NSInternalInconsistencyException
                               reason:[NSString stringWithFormat:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)]
                             userInfo:nil];

这样就不需要从方法中添加return语句了。

如果抽象类实际上是一个接口(即没有具体的方法实现),使用Objective-C协议是更合适的选择。

Cocoa不提供任何所谓抽象的东西。我们可以创建一个只在运行时检查的类抽象,而在编译时不检查。

不,在Objective-C中无法创建抽象类。

你可以模拟一个抽象类——通过让methods/ selectors调用doesNotRecognizeSelector:从而引发一个异常,使该类不可用。

例如:

- (id)someMethod:(SomeObject*)blah
{
     [self doesNotRecognizeSelector:_cmd];
     return nil;
}

你也可以为init这样做。