Objective-C中与Java的包相对应的是什么?您如何在Objective-C中分组和组织类?
Objective-C中与Java的包相对应的是什么?您如何在Objective-C中分组和组织类?
Objective-C没有与Java包或C ++命名空间相当的内容。部分原因是Objective-C最初只是在C的非常薄的运行时层之上添加对象的,使用了最少的麻烦。不幸的是,对我们来说,当使用Objective-C时,命名冲突是我们必须处理的一件事情。你赢得了一些,你输掉了一些......
一个小的澄清(虽然这并不能让人感到安慰)是Objective-C实际上有两个扁平的命名空间 - 一个用于类,另一个用于协议(如Java的接口)。这不解决任何类名冲突,但它确实意味着您可以拥有具有相同名称的协议和类(例如<NSObject>和NSObject),其中后者通常采用(“实现”)前者。此功能可以防止Java中猖獗的“Foo / FooImpl”模式,但遗憾的是它无法解决类冲突。
命名
以下规则是主观的,但它们是命名Objective-C类的不错指南。
虽然拥有包/命名空间机制会很好,但不要指望它会发生。实际上,类冲突相当少见,而且通常在发生时非常明显。命名空间对于Objective-C来说是一个不存在的问题的解决方案。(此外,添加命名空间将消除前缀等变通方法的需要,但可能会在方法调用等方面引入更多的复杂性。)
方法冲突导致的更加微妙和狡猾的错误,这些冲突可能是由子类还是分类(Categories)添加和/或覆盖的方法所导致的。这样做可能会导致令人讨厌的错误,因为分类的加载顺序是未定义的(非确定性的)。实现分类是Objective-C中最尖锐的边缘之一,只有当你知道自己在做什么时才应该尝试,特别是对于第三方代码,尤其是Cocoa框架类。
他们使用很长的名称...
很遗憾,Objective-C没有类似于C#、C++的命名空间或Java的包的等价物。
可以通过给出上下文名称来解决命名冲突。例如,如果您要为方法命名,则应该暗示所属的类和模块,以便避免这些问题。
请查看以下网址,了解苹果建议的命名约定更多信息。
这样的东西怎么样(在一个目录内)?
#define PruebaPaquete ar_com_oxenstudio_paq1_PruebaPaquete
@interface ar_com_oxenstudio_paq1_PruebaPaquete : NSObject {
并像这样导入它:
#import "ar/com/oxenstudio/paq1/PruebaPaquete.h"
PruebaPaquete *p = [[PruebaPaquete alloc] init];
当您遇到名称冲突时:
#import "ar/com/oxenstudio/paq1/PruebaPaquete.h"
#import "ar/com/oxenstudio/paq2/PruebaPaquete.h"
ar_com_oxenstudio_paq1_PruebaPaquete *p = [[ar_com_oxenstudio_paq1_PruebaPaquete alloc] init];
ar_com_oxenstudio_paq2_PruebaPaquete *p2 = [[ar_com_oxenstudio_paq2_PruebaPaquete alloc] init];
嗯,我认为这里所有其他答案似乎都集中在命名冲突上,但至少错过了一个重要特性,即Java包提供的包私有访问控制。
当我设计一个类时,我发现很常见的情况是我只想让一些特定的类调用它的方法,因为它们一起工作以完成任务,但我不希望所有其他无关的类调用那些方法。这就是Java包访问控制派上用场的地方,所以我可以将相关的类分组到一个包中,并使这些方法具有包私有访问控制。但在Objective-C中没有办法做到这一点。
没有包私有访问控制,我发现很难避免人们编写像这样的代码:[[[[[a m1] m2] m3] m4] m5]或[a.b.c.d m1]
。
更新:Xcode 4.4引入了“Objective-C类扩展头文件”,在我看来,这在某种程度上提供了“包私有访问控制”,因此如果您包括扩展头文件,则可以调用我的“包私有”方法;如果您只包括我的公共头文件,则只能调用我的公共API。