我对Objective-C协议和类别的一些概念感到困惑。
协议和类别可以由Objective-C中的子类继承吗?
答案 0 :(得分:31)
类别是在运行时添加到类的方法的集合。因为Objective-C使用动态绑定,这意味着类中定义的方法可用于类及其所有子类。特别是选择器在调用它们时绑定到方法,而不是在编译期间或程序首次加载时。在加载类别时,类别会添加到类中。
协议定义方法签名的集合,符合它们的类承诺实现。一旦类声明它符合协议,就好像方法在该类的接口中声明并且继承规则完全相同:子类继承协议方法的声明和实现,但也可以选择覆盖超类实施
可以扩展协议本身以生成新协议。由原始协议中方法的超集组成。实际上,正如大多数类继承自NSObject
类一样,大多数协议都扩展了NSObject
协议(协议名称和类名称位于不同的名称空间中)。这样,声明为id<WhateverProtocol>
的对象可以发送基本消息,如-retain
,-release
等,而不会生成编译器警告。
答案 1 :(得分:6)
类别就像是类的扩展。您可以将自己的方法添加到其他类(例如NSString或其他任何类)。这意味着任何子类都可以获取方法。
协议是一个方法列表,要求确认它的类实现所有方法(除非它使用@optional标记)。所以它的子类没有必要继承它。
修改强>
对于协议实现,我意识到我不够清楚。协议在其超类中实现的方法可以继承,但是,我的意思通常是你不需要覆盖超类的协议方法。
答案 2 :(得分:4)
你的问题不清楚。您可能会问,子类是否继承了其超类的协议和类别。 @theAmateurProgrammer已经回答了这个问题。
您可能还在询问类别和协议本身是否可以继承其他类别和协议。对于类别,答案是否定的。对于协议,答案是肯定的,事实上协议应该几乎总是像这样的类继承:
@protocol SomeProtocol <NSObject>
...
@end
这表示符合<SomeProtocol>
的任何内容也符合<NSObject>
(这是一个协议以及一个类)。这允许您调用respondsToSelector:
之类的方法,这对于大多数协议实现非常重要。
答案 3 :(得分:2)
协议就像Java中的接口。因此,类提供了访问它的协议。
您可以像Java一样“子类化”协议,您可以“子类化”接口。
另一方面,类别是一种向类添加更多方法的方法。限制是您不能添加任何类别的实例变量。您只能访问现有的实例变量。
它非常有用,因为它避免了创建一个大的脆弱的子类层次结构。
因此,如果您希望视图不同的类符合标准接口,那么底线是,然后使用协议。如果您想在没有子类化麻烦的情况下向现有类添加一些方法,请选择一个类别。
然而,要记住的一件事是,当你为一个类别添加方法时 - 我被工友们提醒过的事情 - 是你在任何地方都可以使用这些方法。我在一些地方读到,一个常见的新手错误就是对类别感到疯狂,一直使用它们而不是创建可以完成工作的新类。
因此,如果您正在考虑的新类别方法确实是特定的,或者更确切地说 - 与业务功能紧密耦合,那么它可能不应该是一个类别。它们实际上只应用于基类的通用添加。
答案 4 :(得分:1)
NSObject符合NSObject协议
@interface NSObject <NSObject> {
Class isa OBJC_ISA_AVAILABILITY;
}
假设我们有一个NSObject的子类
@interface FTGAnimal : NSObject
@end
@implementation FTGAnimal
@end
我们可以看到FTGAnimal实际上符合NSObject协议
if ([FTGAnimal conformsToProtocol:@protocol(NSObject)]) {
NSLog(@"FTGAnimal conforms to NSObject protocol");
}