在Java中,您可以将多个构造函数放入一个被调用的类中,具体取决于构造实例时使用的参数的类型和/或数量。 我假设在Objective C中有等价物。
我可以使用多态方法吗?
我想构建一个方法,根据字符串是传递还是双精度,行为略有不同?
这听起来有点疯狂吗?或者这很容易吗?
答案 0 :(得分: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
的{{1}}或NSNumber
。然后,在方法的实现中,使用Objective-C的内省方法来确定如何继续:
double
这种方法基本上告诉来电者“发送任何东西 - 我会妥善处理它”。如果没有大量文档,很难确定这种方法的行为。
答案 1 :(得分:2)
绝对容易:
- (id)initWithSomeObject:(id)object
{
if ([object isKindOfClass:[ClassOne class]) {
// do something
} else if ([object isKindOfClass:[ClassTwo class]) {
// do something else
} // etc.
return self;
}
答案 2 :(得分:1)
所以您会看到initWithDouble:
,initWithBool:
等内容。这部分原因在于它对某些人的品味有点“罗嗦”。
使用你的例子:
@interface MONClass
- (id)initWithString:(NSString *)pString;
- (id)initWithDouble:(double)pDouble;
...
但以下是错误:
- (id)initWith:(NSString *)pString;
- (id)initWith:(double)pDouble;
因为选择器是相同的 - 选择器中省略了参数/返回类型。
答案 3 :(得分:1)
基本上,Objective C没有适当的方法重载。它只支持覆盖。 假设您编写类似于同一类的函数,
这将支持目标C. 假设您编写了像
这样的函数这样编译器会给出Error,因为showMethod的实现中存在冲突的参数类型。