一、Categories(分类)
     Categories是一个把单个类定义分作好几个文件的方式。它的目标是通过模块化减少代码量比较大的压力。这避免了你的代码成为1000+行的文件,这样操作和分配精确几乎是不可能的。一个好的类定义是一个独特开发者必须的。
          
     这个图是用多个文件来实现Car类。
 
           在这个模块,我们在不接触它的类原始文件的情况下,使用分类来扩展已经存在的类。我们将学到如何使用这个功能来仿生保护方法(Protected methods)。Extensions和category关联很大,一会再说。
     设置
           再我们开始试验categories时,我们需要一个类去操作,创建/改变你的已经存在的类,代码如下:
       Car.h
#import <Foundation/Foundation.h>

@interface Car : NSObject

@property(copy,nonatomic)NSString *model;
@property(readonly) double odometer; -(void)startEngine;
-(void)drive;
-(void)turnLeft;
-(void)turnRight;
@end
它的实现知识一些描述消息,因此我么可以再不同方法调用时发现。
#import "Car.h"
@implementation Car

-(void)startEngine
{
NSLog(@"starting the %@'s engine" ,_model);
}
-(void)drive
{
NSLog(@"The %@ is now driving",_model);
}
-(void)turnLeft
{
NSLog(@"The %@ is turning left",_model);
}
-(void)turnRight
{
NSLog(@"The %@ is turn right",_model);
}
@end
现在,让我们添其他方法到Car中,我们不去操作Car.h或者Car.m文件,我们可以用一个专用的分类去放置自己的函数方法。
创建Categories
     File—>New File—>iOS中选择Source—>Objective-C File,然后就会看到下图的选项,File Type 包括Empty File,Category,Protocol和Extension。
          File是文件名,Class是你想要扩展的类。
          当我们创建完成后,会生成两个文件,一个Car+Maintenance.h和一个Car+Maintenance.m
           Car+Maintenance.m
#import "Car+Maintenance.h"

@implementation Car (Maintenance)

@end  
       分类名字的约束是一个类的不同分类名字不能相同。正宗的文件命名协定是用类名+分类名。
        在Car+Maintenance.h
#import "Car.h"

@interface Car (Maintenance)

@end
     我们可以看到,它几乎和其他的类一样,只不过多了一个小括号,里面是分类名称,让我们添加一些新的方法到这里:
#import "Car.h"

@interface Car (Maintenance)

-(BOOL)needsOilChange;
-(void)changeOil;
-(void)rotateTires;
-(void)jumpBatteryUsingCar:(Car *)anotherCar;
@end
     在运行的时候,他们就会成为类的一部分,尽管他们没有在一个文件中声明,你可以像访问原始文件中的方法一样去访问分类中的方法。
     当然了,你必须去实现这些方法。它的实现和原始文件实现几乎一样,除了类名称后面多了一个括号。
#import "Car+Maintenance.h"

@implementation Car (Maintenance)

-(BOOL)needsOilChange {
return YES;
}
-(void)changeOil {
NSLog(@"Changin oil for the %@",[self model]);
}
-(void)rotateTires {
NSLog(@"Rotation tires for the %@",[self model]);
}
-(void)jumpBatteryUsingCar:(Car *)anotherCar {
NSLog(@"Jumped the %@ with a %@",[self model],[anotherCar model]);
}
@end
    还有重要的一点,分类也可以用于重写在原始类文件中已经存在的方法,(例如startEngine method),但是千万不要这样做。原因是分类是扁平式组织结构,如果你重写已经存在的方法,OC就不知道该调用哪个方法,在这种情况下,子类化是一个更好的选择。
  使用Categories
    要想使用分类只需要把.h文件导入即可,这样分类中的方法即可使用。
  #import "Car+Maintenance.h"
如果你删除了分类,那么你就会找不到定义的方法。
  保护方法(Protected)
     但是,分类并不是简单的把类定义放到几个文件中,他是一个强大的组织工具。我们可以定义类似保护访问的修改器,方法是在一个专用的分类中,定义一个protected 接口,然后之把它导入父类实现文件中,这样就定义了保护方法,而且使它们保持隐蔽。例如我们创建Car+Protected.h,然后直接导入父类的实现文件中。
#import "Car.h"
#import "Car+Protected.h" @implementation Car
...
- (void)drive {
[self prepareToDrive];
NSLog(@"The %@ is now driving", _model);
}
...

就像上边这样。

二、Extensions(扩展)
     它和分类很像,都是在原始类文件之外,允许你添加新的方法。但是与分类形成对照。extension’API必须再主实现中实现,它不能在分类中实现。
     记住一点,私有方法可以用把分类引入到实现文件中(而不是接口文件)实现私有效果,这些再你有很少的私有方法时可以实现,但是对于一个比较大的类就显得比较笨拙,扩展就是解决这个问题,它允许你声明正式的私有API.
     例如,如果你想把engineIsWorking方法正式的加入到Car中,你可以在Car.m包括一个扩展.它仍是一个私有方法,扩展的语法就像一个空的分类。
#import "Car.h"
@interface Car ()
-(BOOL)engineIsWorking;
@end
     它只有一个.h文件。然后在Car.m中去实现:
#import "Car.h"
#import "Car_Car.h"
@implementation Car -(void)startEngine
{
NSLog(@"starting the %@'s engine" ,_model);
}
-(void)drive
{
NSLog(@"The %@ is now driving",_model);
}
-(void)turnLeft
{
NSLog(@"The %@ is turning left",_model);
}
-(void)turnRight
{
NSLog(@"The %@ is turn right",_model);
}
-(BOOL)engineIsWorking {
return YES;
}
@end
     另外,为了声明一个正式的私有API,扩展还可以重定义属性。这通常是用来使属性就像读写属性一样,同时保持只读到其他对象中。
     例如:
#import "Car.h"

@interface Car ()
@property(readwrite) double odometer;
-(BOOL)engineIsWorking;
@end
     我们可以在内部实现中指定self.odometer的值,但是再Car.m外就会编译失败。
三、总结
     分类是把类模块化道不同文件中的一种方式。扩展提供相似的功能,除了他的API必须要在主实现中公开。
      在组织大量代码库时,最常见的分类使用就是给内置数据类型(NSString 、NSArray)添加方法。这样的优点在于,你不需要去创建一个子类更新存在的代码,但是必须要小心不要去重写已经存在的方法。对于小的工程,分类完全没有必要使用,可以用协议或者子类化去实现这种功能。
     
     

Categories  VS Extensions (分类 vs 扩展)的更多相关文章

  1. iOS开发---分类和扩展(Categories和Extensions)

      1.分类能够做到的事情主要是:即使在你不知道一个类的源码情况下,向这个类添加扩展的方法.   此外,分类能够保证你的实现类和其他的文件区分开.   1 #import “UIViewControl ...

  2. (转)iOS分类和扩展(Categories和Extensions)

    分类(Category)   分类能够做到的事情主要是:即使在你不知道一个类的源码情况下,向这个类添加扩展的方法.   此外,分类能够保证你的实现类和其他的文件区分开. #import “UIView ...

  3. iOS 类别和扩展(Categories和Extensions)

    分类(Category)   分类能够做到的事情主要是:即使在你不知道一个类的源码情况下,向这个类添加扩展的方法.   此外,分类能够保证你的实现类和其他的文件区分开.   1 #import “UI ...

  4. iphone 开发Categories 、Extensions 区别 --转

    Category和Extension这两个概念,即便对于Java程序员,可能也会感到陌生.这是Objective C为程序员提供的两个强大的动态机制——简单地说,它们允许程序员为已有的对象添加新的方法 ...

  5. 8.2.1.7 Use of Index Extensions 使用索引扩展

    8.2.1.7 Use of Index Extensions 使用索引扩展 InnoDB 自动扩展每个secondary index 通过添加primary key columns to it,考虑 ...

  6. iOS项目开发日常之创建文件(协议、类、分类、扩展)

    iOS项目开发过程中,是以不断创建文件的形式进行着的. 创建得比较频繁的文件类型是: 这两个类型中创建的文件有:子类.分类.扩展.协议四种文件,如下:    这四类文件是频繁创建的,我们来看一下各自分 ...

  7. iOS中的分类和扩展

    一.什么是分类? 概念:分类(Category)是OC中的特有语法,它是表示一个指向分类的结构体指针.根据下面源码组成可以看到它没有属性列表,原则上是不能添加成员变量(其实可以借助运行时功能,进行关联 ...

  8. Swift基础--Swift中的分类以及在分类中扩展init方法的注意事项

    Swift中的分类 1.创建一个空的swift文件 2.关键字extension,格式: extension 要扩展的类名 {} extension UIButton { } Swift中扩展init ...

  9. Celery-4.1 用户指南: Extensions and Bootsteps (扩展和Bootsteps)

    自定义消息消费者 你可能想要嵌入自定义的 Kombu 消费者来手动处理你的消息. 为了达到这个目的,celery 提供了一个 ConsumerStep bootstep 类,你只需要定义 get_co ...

随机推荐

  1. IDEA中SpringBoot项目快速创建单元测试

    如何在IDEA中对于SpringBoot项目快速创建单元测试 创建测试用例 右键需要进行测试的方法,选择GO TO然后选择Test 点击Create New Test 勾选需要创建单元测试的方法 然后 ...

  2. 高可用Hadoop平台-Oozie工作流

    1.概述 在开发Hadoop的相关应用使用,在业务不复杂,任务不多的情况下,我们可以直接使用Crontab去完成相关应用的调度.今天给大家介绍的是统一管理各种调度任务的系统,下面为今天分享的内容目录: ...

  3. Spring读取外部的资源配置文件—@PropertySource和@Value实现资源文件配置

    通过@PropertySource可以指定读取的配置文件,通过@Value注解获取值: @PropertySource注解主要是让Spring的Environment接口读取属性配置文件用的,标识在@ ...

  4. REX:EOS资源租赁平台详解

    关键字:REX,资源交易,资源租赁,系统费用,bancor,成熟期,EOS,eosio.system,voting EOSIO 智能合约在v1.6.0版本增加了一个system合约使用的例子,可提供E ...

  5. Struts2学习(一)————Struts2入门

    首先推荐一本书,虽然我还没看过,但是我以后肯定会看的,<Struts+技术内幕>提取密码:kg6w .现在只是停留在会使用struts2的层次,自己也想继续深入研究,但是感觉自己的知识面还 ...

  6. 初识Scala

    scala 是 scalable Language 的简写,是一门多范式的编程语言. scala是一种纯面向对象的语言每个值都是对象, 同时支持大量的函数式特性. scala运行于Java虚拟机(JV ...

  7. Java并发编程:Java线程池核心ThreadPoolExecutor的使用和原理分析

    目录 引出线程池 Executor框架 ThreadPoolExecutor详解 构造函数 重要的变量 线程池执行流程 任务队列workQueue 任务拒绝策略 线程池的关闭 ThreadPoolEx ...

  8. VisualSVN 手动记录访问操作日志

    一. VisualSVN 是一个可以免费使用的,SVN服务器端软件,基于 apache .可以实现 http https 多种SVN 发布功能. VisualSVN 默认是没有日志记录功能,需要手动打 ...

  9. Linux将未挂载的磁盘挂载到目录

     1.找的未挂载磁盘fdisk -l2.格式化mkfs -t ext4 /dev/xvdc3.挂载目录mount /dev/xvdc /data4.开机启动vi /etc/fstab/dev/xvdc ...

  10. SOA、SOAP、RFC、RPC、IETF

    SOA: 全称:Servuce - oriented Architecture 说明:面向服务架构 就是说将软件按照功能设计成一个个服务,这些服务用标准的方式定义接口.并通过标准的协议进行调用. SO ...