Referring to Classes - @class(@class关键字)
视频锁定
{$ currentTime | date:'mm:ss' $}
{$ timeLeft | date:'mm:ss' $}
仅仅是提到了一个类的名字,而没有引入这个类的interface文件,在Objective-C中,提供了这样的功能---@class
。当你只想告诉编译器一个类名而不想将类的声明全部引入的时候,这个功能就非常有用了。
举个例子,我仅仅想告诉编译器,有Border
和Square
这两个类,但不想引入他们的声明,具体的表达式如下:
@class Border, Square;
当实例变量、返回值、参数都是静态类型时,无具体声明体的类名也可以出现在一个类的声明文件中,如下:
#import "Foundation/NSObject.h"
@class Point
@interface Square : NSObject
{
@protected
Point *lowerLeft;
float sideLength;
}
+ (id) newWithLowerLeft: (Point *)lowerLeft sideLength: (float)sideLength;
- (id) initWithLowerLeft: (Point *)lowerLeft sideLength: (float)sideLength;
- (Point *) lowerLeft;
- (float) sideLength;
- (void) setLowerLeft: (Point *)newLowerLeft;
- (void) setSideLength: (float)newSideLength;
@end
通过上面的代码我们可以看到,Point
类仅仅是用@class Point;
做了一个声明。因为Point
这个类对于Square
这个类的声明来说,只用到了实例变量和方法的声明中。所以直接用@class Point;
简单交代一下就完全足够了。
另一方面,真正实现Point
这个类的实现文件肯定会将Point
类的全部声明#import
进来的,所以也不需要在Square
类声明文件中再#import
一回Point
类的声明了。
当然,你用@class Point;
后,编译器就没有办法做Point
类的类型检查(检查Point类可以接收哪些消息),所以编译器会报出一个warning(警告),但这并不影响成功编译。
但是,有一种情况你是不能用@class
的,那就是当你定义一个新的类的时候,这个类继承于其他类,也就是这个新的类是有父类的,你就不能简单的用@class
父类的方式。你必须老老实实地使用#import
或者#include
方式,将父类的完整声明引入你的声明文件中来。否则由于编译器并不知道你的父类的具体细节以及它的实例变量,所以编译器将没法编译。
在线练习
{$ activeFileHint $}