2011-08-21 114 views
67

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

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

+0

类别是实际代码。他们是如何为课程添加功能的。扩展(非常笼统地说)更多的是语法糖,用于向其他程序员发送关于隐私等的某些想法。扩展名不包含代码,并且不包含代码。 – Fattie

+0

对于在Swift中使用的扩展,请参阅此问题:http://stackoverflow.com/questions/24142829/how-to-create-swift-class-for-category – Suragch

回答

77

主要区别在于,使用扩展名时,编译器会期望您在主要的@implementation内执行方法,而对于类别,您有一个单独的@implementation块。所以你应该几乎只使用主文件.m文件顶部的一个扩展名(顺便说一下,你应该关心ivars的唯一的地方) - 它的意思就是,扩展名为

+3

但是那么使用扩展类别? – David

+32

扩展最适合您想要在'.m'文件中声明的私有方法。我一直都在使用它。当你想将你的方法分成不同的部分时,类别更有用 - *类别* :) - 或者当你想添加代码到你没有创建的现有类时。 – jtbandes

+1

您还可以使用属性添加额外的存储是类扩展。 –

3

类别是一种Objective-C语言功能,可让您将新方法添加到现有类中。扩展是类别的一种特殊情况,它允许您定义必须在主实现块中实现的方法。

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

+0

”必须在主实现块中声明“。 - >必须在主要实现块“执行” – Fawkes

+0

谢谢,我修改了它。 –

0

IOS扩展类同C#,Java抽象类或接口
IOS类别类同C#类扩展

+0

Java不支持扩展方法 – someUser

+0

抱歉!复制粘贴错字。 ios类似于c#类的扩展。 – Add080bbA

15

甲类扩展具有一些相似性类别,但它可以只被添加到一类用于其您在编译时有源代码(该类与类扩展同时编译)。由类扩展声明的方法在原始类的@implementation块中实现,因此您不能在框架类(例如Cocoa或Cocoa Touch类,如NSString)上声明类扩展。

声明一个类扩展的语法类似于语法类别,看起来是这样的:

@interface ClassName() 
@end 

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

与常规类别不同,类扩展可以将自己的属性和实例变量添加到类中。如果你在一个类扩展声明属性,像这样:

@interface XYZAnimal() { 
    id _someCustomInstanceVariable; 
} 
... 
@end 

恕我直言,这是最好把类扩展为专用接口的一类。主要接口(在你的.h文件中)充当定义类与其他类的行为契约的公共接口。

使用类扩展到隐藏个人信息

类的外延经常被用来公共接口与类本身的执行中使用额外的私有方法或属性扩展。例如,在接口中将属性定义为只读属性很常见,但在类实例上方声明的类扩展中使用readwrite,以便类的内部方法可以直接更改属性值。

作为一个例子,XYZPerson类可能会添加一个名为uniqueIdentifier的属性,该属性旨在跟踪美国社会保险号码等信息。

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

@interface XYZPerson : NSObject 
    ... 
    @property (readonly) NSString *uniqueIdentifier; 
    - (void)assignUniqueIdentifier; 
@end 

为了使XYZPerson类能够在内部更改属性,是有意义的重新声明属性的人提供在该类的实现文件的顶部定义一个类扩展:

@property (readwrite) NSString *uniqueIdentifier; 

注意:readwrite属性是可选的,因为它是默认值。为了清晰起见,您可能会在重新声明财产时使用它。

-1

类别是扩展现有类的API的一种方式,而扩展是在主界面文件之外向API添加所需方法的一种方法。这两者最初都是为了减轻维护大型代码库的负担而设计的。使用类别的

注意事项:

1-不能可靠地覆盖类别定义的相同类的方法。

2-一个类别不能添加实例变量。这意味着你不能声明新的属性。

参考:Objective-C Succinctly: Categories and Extensions。它通过实例进行了详细的讨论。