分类和扩展

简介:

原来写过一个解释很详细的分类和扩展的博客,感觉不是太直观,但是讲的很详细,今天就以一个简单的小例子来讲解一下。

首先是分类(Category)

它的作用就是为一个已有的类添加新的方法。说白了就是对类的扩展。看一下下面的例子:

首先我们新建一个Person类,该类继承自NSObject:

Person.h

#import <Foundation/Foundation.h>

@interface Person : NSObject

@end

Person.m

#import "Person.h"

@implementation Person

@end

我们可以在该类中声明我们需要的属性和方法。然后使用该类。这些都没有问题。但是有个比较奇葩的想法。我想让NSObject有个eat的方法,然后我在Person中去直接使用,就相当于调用了父类的eat方法,而且这个方法还不能在Person中实现。所以就会想到通过分类实现。

我们可以新建一个分类:File-->new-->然后在iOS中选择Objective-C File,然后填写File名称,File Type:(Extension/Protocol/Category/Empty File)。我们选择Category,然后设置Class为NSObject(Person的父类)。这里File名称我定为Category。完成后我们就会看到项目中多了两个我们刚才新建的那两个文件:

NSObject+Category.h和NSobject+Category.m。这就是我们新建的分类文件。看一下他的内容:

NSObject+Category.h:

#import <Foundation/Foundation.h>

@interface NSObject (Category)

@end

NSobject+Category.m

#import "NSObject+Category.h"

@implementation NSObject (Category)

@end

然后我们可以对上面的类中添加方法eat,添加过后的代码:

NSObject+Category.h

#import <Foundation/Foundation.h>

@interface NSObject (Category)

- (void)eat;
@end

NSObject+Category.m

复制代码
#import "NSObject+Category.h"

@implementation NSObject (Category)

- (void)eat {
    NSLog(@"调用分类中的文件,然后使劲吃");
}
@end
复制代码

这样一个添加有eat方法的NSObject分类就建好了。该怎么使用呢?看下边:

我们直接在Person.h中导入NSObject+Category.h文件:

#import <Foundation/Foundation.h>
#import "NSObject+Category.h"
@interface Person : NSObject

@end

然后我们就可以在ViewController或者main类中开始使用了:(我是在ViewControlelr中直接使用的)

复制代码
#import "ViewController.h"
#import "Person.h"
@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    Person *person = [Person new];
    [person eat];
    // Do any additional setup after loading the view, typically from a nib.
}

@end
复制代码

这样我们实例化的person就有了eat的方法了。

什么?项目中有什么用?

在项目中,举个栗子,在项目中我们可能会去处理时间,比如让时间以指定的格式去显示,这个时候可能项目中有好多地方都需要去使用这个时间处理。我们总不能一个一个都写吧,我们可以新建一个NSDate的分类,然后在里面写一个类方法。这样我们在需要的地方直接去导入该NSDate的分类,然后直接使用就行了。(当然你也可以直接在BaseViewController中或者Global中去定义,都可以)。

看的累么?如果累就继续往下看扩展吧。

什么是扩展勒?刚才你会发现我们用分类给已有的类添加了新的方法,那么你可以不可以在分类中添加新的属性呢?你可以试试。我试了,不行,不行,不行。那怎么办?那就靠扩展了。它可以给已有的类添加属性。那么厉害?对,就是那么厉害?

就那刚才的Person类,我们想定义一个idCard属性,要求不能在Person.h中定义,那么我们可以新建一个NSObject的扩展。怎么建呢?和刚才建分类一样,只不过把File Type改成Extension就行了。建完后会看到这个:

由于我输入的File name是Extenstion所以在项目文件夹里多了一个文件。一个文件?对的,没有错扩展只是生成了一个NSObject_Extension.h文件。.m不知道跑哪里了。添加idCard的扩展如下:

复制代码
#import <Foundation/Foundation.h>

@class NSString;
@interface NSObject ()

@property (nonatomic,copy)NSString *idCard;
@end
复制代码

怎么使用呢?和刚才一样,导入.h即可:

复制代码
#import "ViewController.h"
#import "Person.h"
#import "NSObject_Extenstion.h"
@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    Person *person = [Person new];
    [person eat];
    person.idCard = @"1312323423534543";
    // Do any additional setup after loading the view, typically from a nib.
}

@end
复制代码

这样我们的Person类就有一个属性idCard了。

 

说了这么多?你应该可以理解把?不理解?看看下边的总结:

 

----------------------------------------------这里是总结----------------------------------------------

1、分类(Category)是可以给现有的类去添加方法的。但是注意尽量不要去重写该类已有的方法。(我刚才试了一下,直接Crash了,还提示分类正在实现一个该类自身的私有类警告)。反正不管怎么着,尽量不要去重写该类的方法。

2、扩展(Extension)是可以给现有的类添加属性(实例变量)的。

3、你说可以在扩展中添加方法吗?你试试。我试了,不行,再说了,要知道在扩展里添加方法我们去哪里实现呢?.m都没有。。。。

4、你说可以在分类中添加属性吗?你也试试,我试了(添加name)。再分类的.m文件中说name需要name方法定义-使用@dynamic或者提供方法来实现在category中。我定义之后还是直接Crash。说明在分类中添加属性行不通。

----------------------------------------------结束语----------------------------------------------

就这么多吧,如果有什么错误欢迎指正。谢谢。

---------------------------------------------修改----------------------------------------------

1、上面总结的第四条中,分类中是不能添加实例变量,但是可以添加属性。

相关文章
|
6月前
|
机器学习/深度学习 自然语言处理 算法
【多标签文本分类】《多粒度信息关系增强的多标签文本分类》
提出一种多粒度的多标签文本分类方法。一共3个粒度:文档级分类模块、词级分类模块、标签约束性关系匹配辅助模块。
|
12天前
|
关系型数据库 MySQL 数据库
定义模型和模型配置
定义模型和模型配置。
8 1
|
2月前
|
机器学习/深度学习 自动驾驶 数据可视化
【细粒度】由CUB_200_2011数据集展开讲解细粒度分类任务
【细粒度】由CUB_200_2011数据集展开讲解细粒度分类任务
57 0
【细粒度】由CUB_200_2011数据集展开讲解细粒度分类任务
|
6月前
|
数据采集 机器学习/深度学习 数据处理
类别数据处理:你必须知道的技巧与方法
类别数据处理:你必须知道的技巧与方法
51 0
|
8月前
|
机器学习/深度学习 自然语言处理 BI
FourIE:基于图卷积网络的跨任务实例表征交互和标签依赖的联合信息抽取模型
现有的信息抽取(IE)工作主要是分别解决四个主要任务(实体提及识别、关系抽取、事件触发词检测和论元抽取),无法从任务之间的相互依赖中获益。
80 2
|
10月前
|
PyTorch 算法框架/工具
【PyTorch】两种不同分类层的设计方法
【PyTorch】两种不同分类层的设计方法
49 0
|
12月前
|
设计模式 测试技术 持续交付
深入抽象和动态建模(1)
深入抽象和动态建模
114 0
深入抽象和动态建模(1)
【论文写作分析】之二 《基于类别混合嵌入的电力文本层次化分类方法》
【论文写作分析】之二 《基于类别混合嵌入的电力文本层次化分类方法》
【论文写作分析】之二 《基于类别混合嵌入的电力文本层次化分类方法》
|
机器学习/深度学习 算法 机器人
TMM2023 - FECANet:用特征增强的上下文感知网络增强小样本语义分割
TMM2023 - FECANet:用特征增强的上下文感知网络增强小样本语义分割
142 0
TMM2023 - FECANet:用特征增强的上下文感知网络增强小样本语义分割
|
PyTorch 算法框架/工具 索引
pytorch使用None索引进行维度扩展
pytorch使用None索引进行维度扩展
140 0