Objective-C中的方法重载?

Posted

技术标签:

【中文标题】Objective-C中的方法重载?【英文标题】:Method overloading in Objective-C? 【发布时间】:2011-01-18 04:23:19 【问题描述】:

据我所知,Objective-C 不支持方法重载。在 Objective-C 中有什么替代方法?还是我应该总是使用不同的方法名?

【问题讨论】:

【参考方案1】:

正确,objective-C 不支持方法重载,所以你必须使用不同的方法名。

但请注意,“方法名称”包括方法签名关键字(参数 ":"s) 之前的名称,因此以下是两个不同的 方法,即使它们都以“writeToFile”开头:

-(void) writeToFile:(NSString *)path fromInt:(int)anInt;
-(void) writeToFile:(NSString *)path fromString:(NSString *)aString;

(这两个方法的名称分别是“writeToFile:fromInt:”和“writeToFile:fromString:”)。

【讨论】:

@RaheelSadiq 它没有重载,因为方法名称(在 ObjC 中:“选择器”)不同。不同的是,两者都不被认为是“超载”。如果 writeToFile:from: 被定义了两次,只有参数 types 不同,那么这将是重载。如前所述,这在 ObjC 中不受支持,就像在其他语言中一样,包括 Java 和现在的 Swift。 不只是参数名本身,连冒号也是方法名的一部分,所以 -(void) writeToFile:(NSString*)path :(int)anInt;和 -(void) writeToFile:(NSString )path :(NSString)aString;也是不同的方法。【参考方案2】:

可能值得一提的是,即使 Objective-C 不支持 方法 重载,Clang + LLVM 确实支持 C 的 函数 重载。虽然不完全是你'正在寻找,它在某些情况下可能会被证明是有用的(例如,当实现visitor design pattern 的一个稍微被破解的(反对封装)版本时)

这是一个关于函数重载如何工作的简单示例:

__attribute__((overloadable)) float area(Circle * this)

    return M_PI*this.radius*this.radius;


__attribute__((overloadable)) float area(Rectangle * this)

    return this.w*this.h;


//...
//In your Obj-C methods you can call:
NSLog(@"%f %f", area(rect), area(circle));

【讨论】:

有人会认为这个提示,结合方法调配,确实会导致“可重载”的方法......为什么需要idisKindOfClass: 可以随意使用, 是另一回事... @alexgray 我明白你的意思,idisKindOfClass: 涵盖了大多数实际场景。您可能更喜欢重载的一个原因是自动选择最适合的类型,这会产生少量开销来维护显式类型检查。 Clang 文档明确指出,它所做的是为 C 提供 C++ 名称修饰。这基本上只是编译器自动在幕后执行在 Objective-C 中所做的事情,方法是提供以下方法名称通过包含(较长形式)参数类型来区分。【参考方案3】:

David 是正确的,Objective-C 不支持方法重载。从这个意义上说,它类似于 php。正如他还指出的那样,以他示例的方式定义两个或多个具有不同签名的方法是常见的做法。但是,也可以使用“id”类型创建一种方法。通过“id”类型,您可以将任何对象(以及使用 NSNumber 类的任何原语)发送到该方法,然后您可以在方法本身内部测试其类型并在必要时抛出适当的异常。尽管这确实对性能有轻微影响,但除非您处理大量数据,否则它很可能是名义上的或微不足道的。

- (void) writeToFile: (NSString *)path fromObject: (id)object 
    if (!([object isKindOfClass: [NSNumber class]] || [object isKindOfClass: [NSString class]])) 
         @throw [NSException exceptionWithName: @"InvalidArgumentException" reason: @"Unrecognized parameter type." userInfo: nil];
    

这也是一个执行对象类型协议的好地方,可以这样做:

(id<MyProtocol>)object

【讨论】:

以上是关于Objective-C中的方法重载?的主要内容,如果未能解决你的问题,请参考以下文章

Java中的方法覆盖(Overriding)和方法重载(Overloading)是啥意思?

java中的方法重载解析

java中的方法重载

php中的重载以及几个常用的魔术方法示例

Java中的Overload(重载)与Override(重写覆盖)

Javascript中的方法重载