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 是MyClassA 或MyClassB 的实例任一,此代码将编译并在运行时正常工作。
当然,好的做法是在这种情况下定义@protocol:
@protocol MyProtocol
- (void)myMethod
@end
并声明您的MyClassA 和MyClassB 都实现了MyProtocol 协议。你的调用代码看起来像
- (void)someOtherMethodInAnOtherClassWithObject:(id<MyProtocol>)obj
{
[obj someMethod];
}
如果你试图调用someOtherMethodInAnOtherClassWithObject:,编译器会给你一个警告/错误(取决于-W标志),传递一个不实现MyProtocol接口的类型的对象。
注意id<MyProtocol> 不是泛型类型,它是您声称实现MyProtocol 协议的id 类型的实例。另请注意,客户端代码的第一个版本运行良好,因为真正重要的是obj 是否可以响应-myMethod 选择器。