关于C#:类扩展与类类别

Class extension vs class category

类扩展@interface Class ()更强大,可以向类中注入变量。类别@interface Class (Category)不能。

还有什么其他的区别,什么时候应该在类扩展上使用类别?


主要区别在于,对于扩展,编译器希望您在主@implementation中实现方法,而对于类别,您有一个单独的@implementation块。所以您应该只在主.m文件的顶部使用一个扩展名(顺便说一下,这是您唯一应该关注ivar的地方)--它的意思就是,一个扩展名。


类扩展与类别有一些相似之处,但它只能添加到编译时具有源代码的类中(类与类扩展同时编译)。类扩展声明的方法在原始类的@implementation块中实现,因此,例如,您不能在框架类(如cocoa或cocoa touch类,如nsstring)上声明类扩展。

声明类扩展的语法与类别的语法类似,如下所示:

1
2
@interface ClassName ()
@end

因为括号中没有名字,类扩展通常被称为匿名类。

与常规类别不同,类扩展可以向类添加自己的属性和实例变量。如果在类扩展中声明属性,如:

1
2
3
4
5
@interface XYZAnimal () {
    id _someCustomInstanceVariable;
}
...
@end

imho,最好把类扩展看作类的私有接口。主接口(在.h文件中)充当公共接口,用于定义类与其他类的行为契约。

使用类扩展来隐藏私有信息

类扩展通常用于使用附加的私有方法或属性扩展公共接口,以便在类本身的实现中使用。例如,通常在接口中将属性定义为只读,但在实现上方声明的类扩展中定义为读写,以便类的内部方法可以直接更改属性值。

例如,XYZPerson类可能会添加一个名为UniqueIdentifier的属性,用于跟踪信息,如美国的社会保险号。

它通常需要大量的文书工作才能为现实世界中的某个人分配唯一标识符,因此XYZPerson类接口可能会将此属性声明为只读,并提供一些方法来请求分配标识符,如:

1
2
3
4
5
@interface XYZPerson : NSObject
    ...
    @property (readonly) NSString *uniqueIdentifier;
    - (void)assignUniqueIdentifier;
@end

为了让XYZPerson类能够在内部更改属性,有必要在类的实现文件顶部定义的类扩展名中重新声明该属性:

1
@property (readwrite) NSString *uniqueIdentifier;

注意:readwrite属性是可选的,因为它是默认的。为了清晰起见,您可能希望在重新定义属性时使用它。


类别是一个客观的C语言特性,允许您向现有类添加新方法。扩展是类别的一种特殊情况,允许您定义必须在主实现块中实现的方法。

私有声明可以在类扩展中,这主要是一些属性,因为我们在调用方法之前不需要声明它。


iOS扩展到C语言,Java抽象类或接口< BR>iOS类别类似于C类扩展