在Objective-C中创建一个抽象类

在Objective-C中没有直接的抽象类支持,但可以通过多种方式模拟抽象类的行为。这包括使用协议、使方法调用异常、在初始化方法中返回nil,以及在基类中实现协议并在子类中覆盖。虽然没有编译时强制,但可以利用编译器警告来提醒开发者实现必要的方法。
摘要由CSDN通过智能技术生成

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

如果没有,我可以在Objective-C中获得一个抽象类的接近程度?


#1楼

Omni Group邮件列表中

Objective-C目前没有像Java这样的抽象编译器结构。

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

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

我还执行以下操作以防止通过默认初始化程序初始化抽象类。

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

#2楼

不,没有办法在Objective-C中创建一个抽象类。

您可以模拟一个抽象类 - 通过使方法/选择器调用doNotRecognizeSelector:并因此引发一个异常,使该类不可用。

例如:

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

您也可以为init执行此操作。


#3楼

通常,Objective-C类只是按照惯例抽象 - 如果作者将一个类记录为抽象,只是在没有子类化的情况下不使用它。 但是,没有编译时强制实施可以防止抽象类的实例化。 实际上,没有什么可以阻止用户通过类别(即在运行时)提供抽象方法的实现。 您可以通过在抽象类中的那些方法实现中引发异常来强制用户至少覆盖某些方法:

[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协议是更合适的选择。


#4楼

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

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

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

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


#5楼

(更多相关建议)

我希望有一种方法让程序员知道“不要从孩子打电话”并完全覆盖(在我的情况下,代表父母在未扩展时仍提供一些默认功能):

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

优点是程序员将在声明中看到“覆盖”并且知道他们不应该调用[super ..]

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

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

建立像这样的编译器提示会很好,甚至提示什么时候最好预先/后调用超级工具,而

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值