Objective-C协议和类别可以继承吗?

时间:2011-09-19 12:33:52

标签: iphone objective-c ios protocols objective-c-category

我对Objective-C协议和类别的一些概念感到困惑。

协议和类别可以由Objective-C中的子类继承吗?

5 个答案:

答案 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");
}