3

在 Java 中,您可以将多个构造函数放入一个类中,根据构造实例时使用的参数的类型和/或数量来调用这些构造函数。我假设在 Objective C 中有等价物。

我可以有一个多态方法吗?

我想构建一个根据是传递字符串还是双精度字符串的行为略有不同的方法?

这听起来很疯狂还是很容易?

4

4 回答 4

5

您正在考虑重载方法。由于在 Objective-C 中实现动态调度的方式,目前不可能将两个不相关的类型作为参数传递给相同(或同名)的方法并让它理解。

在 Objective-C 中,有两种相关但不同的方法来处理多种输入。让我们使用您的字符串或双精度示例作为可能的输入。在 Java 中,您可能有:

 void applyWidget(String s);
 void applyWidget(double d);

这很好,但不是 Objective-C。在 Objective-C 中,您将使用两个不同的方法名称:

- (void)applyWidgetWithName: (NSString *)name;
- (void)applyWidgetWithValue: (double)value;

每个方法中的逻辑与 Java 版本中的逻辑相同,但不同的名称让编译器将它们视为不同的方法(即使在 Java 中也是如此)。代码也成为自文档化的:通过阅读它,你会得到一个即使没有评论,也能了解正在发生的事情。或者,如果您只需要一个方法名称,则将参数类型更改为id并接受任何对象:

- (void)applyWidget: (id)widget;

然后传递一个NSString或一个NSNumber包装你的double. 然后,在方法的实现中,使用Objective-C的自省方法来确定如何进行:

if ([widget isKindOfClass: [NSString class]]) {
    ...
} else if ([widget isKindOfClass: [NSNumber class]]) {
    double d = [widget doubleValue];
    ...
}

这种方法本质上是告诉调用者“发送任何东西——我会适当地处理它”。如果没有大量文档,可能很难确定这种方法的行为。

于 2012-08-15T13:54:12.127 回答
2

绝对容易:

- (id)initWithSomeObject:(id)object
{
    if ([object isKindOfClass:[ClassOne class]) {
        // do something
    } else if ([object isKindOfClass:[ClassTwo class]) {
        // do something else
    } // etc.
    return self;
}
于 2012-08-15T13:48:59.753 回答
1

是的,但是 objc 没有适当的重载。

所以你会看到类似的东西initWithDouble:initWithBool:等等。这就是某些人的口味有点“罗嗦”的部分原因。

使用您的示例:

@interface MONClass

- (id)initWithString:(NSString *)pString;
- (id)initWithDouble:(double)pDouble;
...

但以下是错误:

- (id)initWith:(NSString *)pString;
- (id)initWith:(double)pDouble;

因为选择器是相同的——选择器中省略了参数/返回类型。

于 2012-08-15T13:48:33.250 回答
1

基本上,Objective C 没有适当的方法重载。它将仅支持覆盖。假设如果你在同一个类中编写函数,

  • (void) 显示方法;
  • (void) showMethod:(int) aNumber;

这将在 Objective C 中支持。假设如果您编写如下函数,

  • (void) showMethod:(NSString*) aString;
  • (void) showMethod:(int) aNumber;

通过这种方式,编译器会给出错误,因为在 showMethod 的实现中存在冲突的参数类型。

于 2015-02-21T06:08:59.937 回答