2

我只是好奇是否可以在 Objective-C 中以 Java 已知的方式声明变量:

Class<?extends SomeType>

例如:我有一个名为 MyClass 的类。它有一个静态方法

+ (void)myMethod

它还有两个子类:MySubclassA 和 MySubclassB。我有这样的代码:

Class myClass;
if(<some condition>) {
  myClass = [MySubclassA class];
} else {
  myClass = [MySubclassB class];
}
[myClass myMethod];

这段代码工作正常,没有编译器警告,但我只是好奇我提到的构造是否以某种方式存在于 Objective-C 中。

谢谢!

4

1 回答 1

1

Objective-C 没有模板(如 C++)或具有类型擦除的泛型类型(如 Java)或运行时泛型类型(如 C#)。与这些语言不同,Objective-C 消息在运行时动态分发(而不是在编译时绑定)。因此,许多用于在 C++、Java 或 C# 中生成与类型无关的代码的系统是不必要的。Objective-C 更喜欢“鸭子类型”,即任何响应给定选择器(消息)的对象都可以通过调用代码来获得该消息,而不管接收对象的类型如何。由于类是 Objective-C 中的对象,因此类方法和实例方法也是如此。

所以,给定

@interface MyClassA : NSObject
{}
 - (void)someMethod;
@end

@interface MyClassB: NSObject
{}
 - (void)someMethod;
@end

调用代码看起来像这样

- (void)someOtherMethodInAnOtherClassWithObject:(id)obj
{
  [obj someMethod];
}

此代码将编译并在运行时正常工作,假设objMyClassA的一个实例MyClassB

当然,好的做法会要求您@protocol在这种情况下定义 a:

@protocol MyProtocol
 - (void)myMethod
@end

并声明你MyClassAMyClassB双方都实现了MyProtocol协议。你的调用代码看起来像

- (void)someOtherMethodInAnOtherClassWithObject:(id<MyProtocol>)obj
{
  [obj someMethod];
}

如果您尝试调用,编译器会给您一个警告/错误(取决于 -W 标志)someOtherMethodInAnOtherClassWithObject:,传递一个不实现MyProtocol接口的类型的对象。

请注意,这不是id<MyProtocol>泛型类型,它是您声称实现协议的类型的实例。另请注意,客户端代码的第一个版本工作得很好,因为真正重要的是是否可以响应选择器。idMyProtocolobj-myMethod

于 2011-03-23T13:21:49.510 回答