在Objective-C中构造“Class <! - ?extends SomeType - >”变量声明

时间:2011-03-23 13:01:19

标签: objective-c class extends

我很好奇是否可以在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中。

谢谢!

1 个答案:

答案 0 :(得分:1)

Objective-C没有模板(如C ++)或类型擦除(如Java)或运行时泛型类型(如C#)的泛型类型。与这些语言不同,Objective-C消息在运行时动态调度(而不是在编译时绑定)。因此,许多用于在C ++,Java或C#中生成类型不可知代码的系统是不必要的。 Objective-C更喜欢“duck-typing”,通过调用代码可以给任何响应给定选择器(消息)的对象,无论接收对象的类型如何。由于类是Objective-C中的对象,因此类方法与实例方法一样。

所以,给定

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

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

调用代码看起来像这样

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

此代码将编译并在运行时正常工作,假设obj MyClassAMyClassB的实例。

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

@protocol MyProtocol
 - (void)myMethod
@end

并声明您的MyClassAMyClassB都实施了MyProtocol协议。您的调用代码看起来像

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

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

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