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

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


当前回答

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

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

例如:

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

你也可以为init这样做。

其他回答

通过应用@dotToString的评论,稍微改变一下@redfood的建议,你实际上得到了Instagram的IGListKit所采用的解决方案。

为所有在基(抽象)类中定义没有意义的方法创建一个协议,即它们需要在子类中特定的实现。 创建一个不实现此协议的基(抽象)类。您可以向该类添加任何其他具有公共实现的方法。 在项目中的任何地方,如果必须通过某种方法输入或输出AbstractClass的子对象,请将其键入为AbstractClass<Protocol>。

因为AbstractClass没有实现Protocol,所以拥有AbstractClass<Protocol>实例的唯一方法是子类化。由于AbstractClass不能单独在项目中的任何地方使用,因此它变得抽象。

当然,这并不能阻止不明智的开发人员添加简单地引用AbstractClass的新方法,这最终将允许抽象类的实例(不再是)。

真实世界的例子:IGListKit有一个基类IGListSectionController,它不实现协议IGListSectionType,但是每个方法都需要这个类的实例,实际上要求类型IGListSectionController<IGListSectionType>。因此,在框架中没有办法使用IGListSectionController类型的对象来做任何有用的事情。

从Omni组邮件列表:

Objective-C没有像Java那样的抽象编译器结构 这一次。

因此,您所要做的就是将抽象类定义为任何其他正常类 并为抽象方法实现方法存根 空或报告不支持选择器。例如……

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

我还执行以下操作来防止抽象的初始化 通过默认初始化式初始化。

- (id)init
{
     [self doesNotRecognizeSelector:_cmd];
     [self release];
     return nil;
}

你不能创建一个委托吗?

委托就像一个抽象基类,你说需要定义什么函数,但实际上你不定义它们。

然后,每当你实现委托(即抽象类)时,编译器就会警告你需要为哪些可选函数和强制函数定义行为。

对我来说,这听起来像一个抽象基类。

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

我想出的解决办法是:

为“抽象”类中需要的所有内容创建一个协议 创建一个实现协议的基类(也可以称之为抽象类)。对于所有你想要“抽象”的方法,在.m文件中实现它们,而不是在.h文件中实现。 让你的子类继承基类并实现协议。

这样,编译器就会对协议中没有由你的子类实现的任何方法发出警告。

它不像Java中那样简洁,但您确实会得到所需的编译器警告。