我已经编写Objective C 将近一年了,我从来没有机会将接口(.h)用于其他目的,而不是声明您可以在实现( .m)中找到的几乎相同的类结构。
由于我来自其他没有Objective C接口之类的语言,我想知道我是否缺少一些或几种用途,或者这只是这种特定语言可能从其前身继承的约定。
谢谢!
我已经编写Objective C 将近一年了,我从来没有机会将接口(.h)用于其他目的,而不是声明您可以在实现( .m)中找到的几乎相同的类结构。
由于我来自其他没有Objective C接口之类的语言,我想知道我是否缺少一些或几种用途,或者这只是这种特定语言可能从其前身继承的约定。
谢谢!
您的接口是该类的公共 API。任何未在接口中声明的东西都不能从类外部访问。如果您更多地考虑 C++ 或 Java,则 .m 文件中的所有内容(未在 .h 中的 @interface 中声明)都是私有的。这就是为什么在 Objective-C 中你不会经常看到它们的关键字 @private、@public 或 @protected。
无论您在界面中放置什么,都是您打算让您的班级用户使用的东西,仅此而已。这遵循最小特权原则。
您还可以将 @interface 视为您的课程的文档。
除了声明几乎可以在实现 (.m) 中找到的类结构之外,我从来没有机会将接口 (.h) 用于其他目的。
该接口是该类的公开声明的接口。实现是它尊重该接口的方式。那么一个简单的例子:
@interface Accumulator: NSObject
- (void)addAmount:(NSUInteger)amount;
@property (nonatomic, assign, readonly) NSUInteger currentTotal;
@end
和:
@implementation Accumulator
{
NSUInteger currentTotal; // an instance variable; we don't want to publish
// these because they're nothing to do with the
// interface we implement. Object orientation means
// not thinking about implementations beyond
// your own.
}
@synthesize currentTotal;
- (void)addAmount:(NSUInteger)amount
{
currentTotal += amount;
}
@end
因此,作为一般准则,您没有放入 @interface 的内容包括:
它继承自 C,其中您有定义接口的标头和包含实现的源文件。这确实意味着一些双重输入。
例如,Java 摒弃了这种两个文件的方法,并有一个包含所有内容的文件。它没有 C 的编译和链接阶段,这是标题的部分原因。
标头方法的一个方面是,使用专有代码,您可以将您的标头连同已编译的二进制文件一起提供给某人,他们可以链接到并调用您的 API。这就是微软对 Win32 API 所做的事情,或者苹果对他们的 SDK 和操作系统所做的事情。
扩展已经说过的内容:基于 C 的语言编译器需要对 .c/.cpp/.m 文件中的单词有一定的了解,然后才能开始链接外部库或目标文件。该信息告诉编译器诸如返回类型和函数和方法的参数的数量和类型,以及类中的实例变量和方法。
如果您实际上将整个 .c/.cpp/.m 文件包含在使用其功能的文件中,那么您最终会遇到一个问题,即链接器具有不知道如何处理的重复代码;因此,头文件仅列出了他们实际需要了解的有关接口的内容,而不是实现。
C 和 Objective-C 实际上允许您省略各种接口信息,但是如果他们看到提到的函数或方法的标题没有阅读,他们就会做出(通常是不正确的)假设。例如,一个未知的函数名将被正确识别,但编译器将假定它返回一个 int;我的记忆对如何处理参数有点模糊,但是如果您传递的参数与最终链接到的已实现函数中的参数不兼容,它可能不会抱怨。因此编译器无法进行大量检查像 C 这样的静态语言擅长。