现在的位置: 首页 > 综合 > 正文

Objective-C 编程语言(6)类别与扩展—-对根类使用类别,扩展

2014年03月06日 ⁄ 综合 ⁄ 共 1508字 ⁄ 字号 评论关闭
转载请标明出处:http://blog.csdn.net/zhangxingping

对根类使用类别

    我们可以使用类别来为任何的类增加方法,这也就包括根类。为NSObject类增加的方法对于代码中的任何类都是可用的。这种方法在某些情况下是很有用的,但同时这样做也是很危险的。尽管,通过使用类别对类所做的修改看起来是很容易理解并且其影响貌似也是有限的,但是继承机制却极大地扩大了这种修改的影响范围。这就可能导致我们对那些自己看不到的类做出了本不应该的修改。这种做法的后果是不能完全预料的。除此之外,那些不知道这种修改的人也很难理解为什么要这样做。
    另外,当我们实现根类的方法时,还需要考虑以下两点:
    ■  不能向super发送消息(根类是没有超类)。
    ■  类对象是可以执行定义在根类中的实例方法的。
    通常情况下, 类对象是只能调用类方法的。但是根类中定义的实例方法是个例外。它们定义了在运行时所有对象都继承的接口。类对象需要共享相同的接口。
    这个特性就意味着我们在为NSObject类使用类别增加接口的时候必须考虑到增加的实例方法不仅仅会被实例对象调用,还有可能被类对象调用。例如,方法中的self可能指示的是实例也可能指示的是类对象。更多关于类对象访问根类实例方法的信息,请参阅基础框架库中关于NSObject类的详细说明。


扩展

    扩展就像是使用无名的类别。不同之处在于使用扩展增加的方法必须在对应的类的@implementation块中进行实现。
一个类中定义了公有的API,同时也定义了仅在本类或者该类所在的框架中才使用的私有API, 这是一件非常普通的事情。我们可以在一个或者多个私有的头文件中通过类别来声明这些私有的API,正如前面所讲到的。但是,编译器此时是不能对所有声明的方法都是否被实现进行验证的。
    如下,针对下面的声明和实现,编译器在编译时不会报告错误:

@interface MyObject: NSObject
{
    NSNumber * number;
}
-(NSNumber *)number;
@end


@interface MyObject(Setter)
-(void) setNumber:(NSNumber*)newNumber;
@end


@implementation MyObject
-(NSNumber*) number
{
    return number;
}
@end

    注意,其中的setNumber:方法没有对应的实现。如果在运行时调用这个方法,就会导致错误。
    扩展使得我们可以不在声明类的@interface代码块中为类声明附加的API。如下面的代码段所示:
    在上面的程序中,有两点需要注意:
    ■  第二个@interface块的括号中是没有任何名称的。
    ■  setNumber:方法的实现是在类的@implementation代码块中的。

@interface MyObject : NSObject
{
    NSNumber * number;
}
-(NSNumber*)number;
@end


@interface MyObject()
-(void) setNumber:(NSNumber *)newNumber;
@end


@implementation MyObject
-(NSNumber *)number
{
    return number;
}


-(void) setNumber:(NSNumber *)newNumber
{
    number = newNumber;
}

setNumber:方法的实现是必须在类的@implementation代码块中的(而不能在类别中实现)。如果没有这样做,编译时就会产生不能找到setNumber:方法的实现的警告。

抱歉!评论已关闭.