Objective-C 基础入门(五)分类与扩展

一、Category 分类

在面对一个类定义时,可能想要添加一些新方法,例如对于 Fraction(分数)类,除了将两个分数相加的 add:方法之外,还想要将两个分数相减、相乘和相除的方法。另外,当参与一个大型程序设计项目,为一个新定义的类编写处理文件系统的方法,并使其模块化

以上情况的实用解决方案就是使用分类 Category。

  • 分类提供了一种简单的方式,将类的定义模块化到相关方法的组或分类中。
  • 分类提供了扩展现有类定义的简便方式,不必访问类的源代码,也无需创建子类。
  • 可以通过未命名分类实现私有方法

以上例子中,以为 Fraction 添加新方法为例,新的 MathOps 分类的接口部分代码如下:

  #import "Fraction.h"
  @interface Fraction (MathOps)
  -(Fraction*) add:(Fraction*) f;
  -(Fraction*) mul:(Fraction*) f;
  -(Fraction*) sub:(Fraction*) f;
  -(Fraction*) div:(Fraction*) f;
  @end

  • 这即是接口部分的定义,也是现有接口部分的扩展,因此需要包括原始接口部分
  • @interface Fraction (MathOps) 告诉编译器正在为 Fraction 类定义名为 MathOps 的分类
  • 实现部分与接口部分相同,通过将分类名称放在类名称之后的圆括号中确定方法所属的分类 @implement Fraction (MathOps)

依照惯例,作为分类的 .h 和 .m 文件的基本名称由类名加分类名组成-FractionMathOps。

category只能给某个已有的类扩充方法,不能扩充成员变量。category中也可以添加属性,不过@property只会生成setter和getter的声明,不会生成setter和getter的实现以及成员变量

如果category中的方法和类中原有方法同名,运行时会优先调用category中的方法。也就是,category中的方法会覆盖掉类中原有的方法。

iOS Category详解 https://www.jianshu.com/p/c92b17a36b9e

二、Extension 扩展

Extension 看起来像一个匿名的 category,和 category 不同的是 extension 不但可以声明方法,还可以声明属性、成员变量。extension 一般用于声明 私有方法、私有属性和私有成员变量

  • 类扩展实现的数据和方法都是私有的,数据和方法仅供这个类本身实用。
  • 类扩展只存在与一个 .h 文件中或者寄生于一个类的 .m 文件中。

  #import "Fraction.h"
  @interface Fraction ( )
  @property (nonatomic) unsigned int officeAlarmCode;
  -(Fraction*) mul:(Fraction*) f;
  @end
  @implementation Employee
   ....

创建一个未命名的分类,且在()之间不指定名字。未命名的分类中声明的方法需要在主实现区域实现,而不是在分离的实现区域中实现。

三、Category 与 Extension 的区别

  • extension 在编译期决议(成为类的一部分),category 在运行时决议。

extension在编译期和头文件里的@interface以及实现文件里的@implement一起形成一个完整的类,extension伴随类的产生而产生,亦随之一起消亡。

  • extension 可以添加实例变量,而 category 无法添加实例变量。

因为在运行期,对象的内存布局已经确定,如果添加实例变量就会破坏类的内部布局,这对编译型语言来说是灾难性的。

  • extension和category都可以添加属性,但是category的属性不能生成成员变量和getter、setter方法的实现。
  • category可以给系统提供的类添加分类,使之模块化。
  • extension一般用来隐藏类的私有信息,无法直接为系统的类扩展,但可以先创建系统类的子类再添加extension。

 

 

 

 

你可能感兴趣的:(Objective-C)