41

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

4

6 回答 6

55

当您在 Objective-C 中编程时,您需要清除诸如虚拟方法之类的东西。您不会在 Objective-C 对象上调用方法,而是向它们发送消息。对象要么响应消息,要么不响应消息,但是由于动态绑定,直到运行时您才能知道这一点。

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

创建“虚拟”基类的最佳方法(在我看来)是声明该方法并为其提供一个引发适当异常的存根实现。

于 2011-03-07T16:31:29.203 回答
33

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

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

另一种方法是只用一个NSAssert(NO, @"Subclasses need to overwrite this method");主体来实现它们。尽管如此,您只能在运行时而不是编译时捕获它。

于 2011-03-07T16:28:18.040 回答
7

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

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

于 2011-03-07T18:18:00.973 回答
6

你应该使用:

- (void)doesNotRecognizeSelector:(SEL)aSelector method. 

正如苹果公司所说,这里:https ://developer.apple.com/library/mac/#documentation/cocoa/reference/Foundation/Classes/NSObject_Class/Reference/Reference.html

于 2013-01-21T11:02:56.103 回答
2

你有几个选择,但你在正确的轨道上。

ObjC 不直接支持这一点,强制子类实现协议是在编译时检查它的最佳方法。

“秘密地”在基类中实现该方法并断言是我所做的,以确认子类在运行时已正确子类化。有些人对断言有复杂的感觉,或者必须让它们保持活跃,所以这并不总是一个好的解决方案。

您还可以强制子类使用特定的类构造函数和初始化序列,然后在返回实例之前验证它们是否已经实现了所需的一切,以防编译器警告没有解决它。

但是 ObjC 缺少一些语言特性,这些特性允许客户在脚下开枪,或者解决他们希望的问题......你不应该太拘泥于强制执行它。

注意:异常在 ObjC 中非常少见(也有点不安全)。

于 2011-03-07T16:40:32.343 回答
0

虚方法是一种方法,其行为可以在继承类中被具有相同签名的函数覆盖(即具有相同数量的参数和参数类型的相同名称)。

例子:-

@implementation BaseClass

-(void)viewDidLoad
{
 [self virtualMethod:123];
}

-(void)virtualMethod:(int)param
{
 //implement this method in subclass
}

@end

///////////////////////////////////////// //

@interface ChildClass:BaseClass
@end

@implementation ChildClass

-(void)virtualMethod:(int)param
{
 NSLog(@"There is no keyword "Virtual" in Objective C.");
}
@end

输出:-

“Objective C 中没有关键字“Virtual”。”

于 2013-04-12T09:18:38.603 回答