在Objective-C中实现纯虚方法

Chr*_*ris 41 methods objective-c pure-virtual

我想去那里.但说真的,如何以"Apple"方式实现纯虚方法?您是否使用基类的协议并在这些方法上抛出异常?

Jer*_*myP 55

在Objective-C中编程时,您需要清除虚拟方法等内容.您不会在Objective-C对象上调用方法,而是向它们发送消息.对象要么响应消息要么不响应消息,但是由于动态绑定,在运行时才能告诉它.

因此,您可以在基础对象上声明一个方法而不是提供实现,没有问题(编译器警告除外),但是当您使用此类方法直接实例化对象时,您不能让编译器标记出来并且它赢了除非您实际将该消息发送到对象,否则不会在运行时抛出错误.

创建"虚拟"基类的最佳方法(在我看来)是声明方法并为其提供一个抛出适当异常的存根实现.

  • 抱歉,假装在ObjC中"发送消息"与函数调用有某种神奇的不同并且需要自己的名字,这简直太傻了.也许它似乎回到了当天,在我们都知道函数绑定不必是静态的之前,但今天我们都知道它们都只是函数,而不管绑定机制如何. (17认同)
  • "选择器"只不过是一流的功能签名,"发送消息"只不过是找到并调用具有该签名的函数.这都是一回事. (13认同)
  • @GlennMaynard不,这不傻.对于从Smalltalk继承的Objective-C的OO模型来说,这是至关重要的.选择器和方法是不同的东西. (8认同)
  • @GlennMaynard我认为没有人假装.当他们写了很多ObjC时,他们只是意识到了微妙的差异.它确实*非常类似于签名发现和方法调用,但**如果你将自己限制在那种思维模型中,你只是错过了很多ObjC的细节.**"发送消息"是_much_ more而不是查找和调用具有该签名的函数.例如,您可以使用NSProxy来转换通过它们传递的消息,或者使用JSON解析器伪对象将getter消息(不存在的方法)视为对JSON哈希键值的访问. (7认同)
  • 虚方法应该看起来: - (UIImage*)getImage {@throw [NSException exceptionWithName:NSInternalInconsistencyException reason:[NSString stringWithFormat:@"你必须在子类中覆盖%@",NSStringFromSelector(_cmd)] userInfo:nil]; } (3认同)

Dar*_*ust 33

在Objective-C中,没有像C++那样的纯虚拟支持.

模拟是您在接口中声明一个方法但不在.m文件中实现它.当然你会得到编译器警告但是IIRC可以关闭它们.但是如果你没有在子类中覆盖它们,你将不会得到警告/错误,这是你在C++(IIRC)中得到的.

另一种方法是仅使用一个NSAssert(NO, @"Subclasses need to overwrite this method");实体来实现它们.但是,你只能在运行时捕获它,而不是编译时.

  • 我喜欢`NSAssert`部分. (4认同)

Mat*_*ens 7

根据您正在执行的操作,委托模式可能比子类更合适,其中委托定义为id<YourDelegateProtocol>.如果未实现委托协议中的所需方法,编译器将生成警告.

在Objective-C中通常避免使用子类,因为对象不能从多个超类继承,但它们可以实现多个协议.

  • Objective-C中的每个对象都是NSObject的子类.所以我要说Subclassing非常重要,而且"通常不会被避免".每次我创建自定义视图,表或控制器时都会发生这种情况. (2认同)
  • @Stephan Furlani不是*objc中的每个*类都是NSObject的子类.a)并非所有objc系统/库都是从nextstep b)派生或继承的,即使只与Apple的库连接,你仍然可以在野外遇到根类(出于各种原因); NSProxy就是一个公开的例子. (2认同)