objective c的分类

本文介绍了Objective-C中分类的概念及应用,详细解释了如何利用分类为现有类添加新方法,而不必修改原有代码或创建子类。适用于扩展框架提供的类、避免子类化以及项目管理和版本控制等场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.分类

使用Object-C中的分类,是一种编译时的手段,允许我们通过给一个类添加方法来扩充它(但是通过category不能添加新的实例变量),并且我们不需要访问类中的代码就可以做到。

我们可以为一个类创建一个新的方法,而不需要在代码中编辑类定义。它提供了扩展类定义的便捷的方式,并且不必访问类的源代码,也无需创建子类。

现在有Fraction类,且接口文件Fraction.h为:


#import <Foundation/Foundation.h>


@interface Fraction : NSObject


@property int numerator,denominator;


-(void) print;

-(void) setTo:(double) n over:(double)d ;

-(double) converToNum;

-(void) reduce;


@end

现在想要向Fraction类添加加减乘除四个方法,则新的分类Mathops的接口部分代码如下:

#import "Fraction.h"


@interface Fraction (MathOps)   //告诉编译器正在为Fraction 类定义新的分类,它的名字为MathOps。


-(Fraction*) add: (Fraction*)f;

-(Fraction*) subtract: (Fraction*) f;

-(Fraction*) multiply: (Fraction*) f;

-(Fraction*) divide: (Fraction*) f;


@end

这既是接口部分的定义,也是现有接口部分的扩展。因此,必须必须包括原有的接口部分。这部分方法声明可以放在主类文件中,此时不需要#import "Fraction.h"。也可以单独放在一个文件中,此时需要在主类的接口文件文件中声明实例变量。
可以将所有方法的实现放在一个实现部分。也就是说,可以在一个实现文件中定义Fraction.h接口部分的所有方法,以及MathOps分类中的所有方法。也可以在单独的实现部分定义分类的方法。
与接口部分一样,通过分类名称括在类名称之后的圆括号中来确定方法的所说分类。语句格式;
 @interface Fraction (MathOpa)
    //分类方法的代码
@end
按照惯例,作为分类的.h和.m文件的基本名称是由类的名称紧接分类的名称。例如:把分类的接口文件命名为FractionMathOps.h,实现文件命名FractionMathOps.m,一些程序员使用“+”来分割主类和分类的名字,比如:Fraction+MathOps.h。

category 与类的关系是多对一,即一个类可以有多个不同方法集的扩展,但是一个category 只能被应用于一个类(待确认)

category的几个典型的应用场景:
1。对框架提供类的扩展(没有源码,不能修改)。
2。 不想生成一个新的子类的情况下,比如对 NSArray 的扩展。
3。 方便做项目管理,可以将一份源码在多个地方共享或者做方法版本管理、多人协作开发、用本地版本替换公共版本实现。
不建议在 category 中覆盖类中的方法,因为在 category 中的方法不能调用 superClass 的方法(因为没有元数据支持)
category 方法不能覆盖于同一class 的其它 category 中的方法。因为不法预知他们的加载优先顺序,就可能在编译时出错。
对类库的 category 方法覆盖对导致整个类库的行为发生变化,因此调用那些方法的类不知道方法的实现已经发生了变化。
警告:
虽然 category 不限于任何 class ,但是仍然不建议编写针对 rootClass 的 category. 原因是影响面较大,其它开发人员如果不注意的话就会出问题。
而且类对象也可能调用这些方法,甚至在调用时的 self 指针不是实例而是类对象本身。

注意事项:

1.分类可以覆盖该类中的另一个方法,但通常不提倡这种做法。当覆盖了一个方法之后就不可以访问原来的方法,因此,必须将被覆盖中的方法中的所有代码复制到替换它的方法中。如果确实需要覆写方法,可以通过创建子类来实现,这样仍然可以通过super来访问父类的的方法,就可以不必了解被覆写的方法的复杂内容,就能够调用父类的方法,并向子类添加新方法。

2,如果同一个方法在多个分类中都定义,调用时不会指定调用哪一个。

3.通过使用分类添加新方法来扩展类不仅会影响这个类,而且影响他的所有子类。例如,如果NSObject添加新方法,对于每个NSObject的子类,都会继承这些新方法。

4.通过分类为现有类添加新方法可能对你有用,但他们有可能和该类的原始设计或意图不一致。例如:通过添加一些新分类和方法来修改Square类的定义,将Square变成Circle。

5.对象/分类命名必须是唯一的。也就是蕾丝这样的@interface NSString (Utilities),因为在objective c的命名空间中,只能存在一个NSString 的分类。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值