OC中类别、扩展、协议与委托

类别(category)——通过使用类别,我们可以动态地为现有的类添加新方法,而且可以将类定义模块化地分不到多个相关文件中。通常只在类别中定义方法。

类别,接口部分的定义,通常该文件命名为已有"类+类别名.h"
@interface 已有类 (类别名)
//.......方法实现
@end

例如,考虑为NSNumber增加一个类别,则接口部分代码如下

<p style="margin-top: 0px; margin-bottom: 0px; font-family: Menlo; color: rgb(209, 47, 27); "><span style="font-size:10px;"><span style="color: rgb(120, 73, 42); ">//"NSNumber+code.h"</span></span></p><p style="margin-top: 0px; margin-bottom: 0px; font-family: Menlo; color: rgb(209, 47, 27); "><span style="font-size:10px;"><span style="color: rgb(120, 73, 42); ">#import </span><Foundation/Foundation.h></span></p><p style="margin-top: 0px; margin-bottom: 0px; font-family: Menlo; "><span style="font-size:10px;"><span style="color: #bb2ca2">@interface</span> NSNumber (code)</span></p><p style="margin-top: 0px; margin-bottom: 0px; font-family: Menlo; "><span style="font-size:10px;"></span></p><span style="font-family: Menlo;font-size:10px; white-space: pre; background-color: rgb(240, 240, 240); ">-(</span><span style="font-family: Menlo;font-size:10px; white-space: pre; background-color: rgb(240, 240, 240); color: rgb(112, 61, 170); ">NSNumber</span><span style="font-family: Menlo;font-size:10px; white-space: pre; background-color: rgb(240, 240, 240); "> *) add:(</span><span style="font-family: Menlo;font-size:10px; white-space: pre; background-color: rgb(240, 240, 240); color: rgb(187, 44, 162); ">double</span><span style="font-family: Menlo;font-size:10px; white-space: pre; background-color: rgb(240, 240, 240); ">) num;</span>
<span style="font-family:Menlo;font-size:10px;"></span><span style="font-family: Menlo;font-size:10px; white-space: pre; background-color: rgb(240, 240, 240); ">-(</span><span style="font-family: Menlo;font-size:10px; white-space: pre; background-color: rgb(240, 240, 240); color: rgb(112, 61, 170); ">NSNumber</span><span style="font-family: Menlo;font-size:10px; white-space: pre; background-color: rgb(240, 240, 240); "> *) mult:(</span><span style="font-family: Menlo;font-size:10px; white-space: pre; background-color: rgb(240, 240, 240); color: rgb(187, 44, 162); ">double</span><span style="font-family: Menlo;font-size:10px; white-space: pre; background-color: rgb(240, 240, 240); ">) num;</span><p style="margin-top: 0px; margin-bottom: 0px; font-family: Menlo; color: rgb(187, 44, 162); "><span style="font-size:10px;">@end</span></p><div>
</div>

该类别的实现部分如下

<p style="margin-top: 0px; margin-bottom: 0px; font-family: Menlo; color: rgb(209, 47, 27); "><span style="font-size:10px;"><span style="color: rgb(120, 73, 42); ">//"NSNuber+code.m"</span></span></p><p style="margin-top: 0px; margin-bottom: 0px; font-family: Menlo; color: rgb(209, 47, 27); "><span style="font-size:10px;"><span style="color: rgb(120, 73, 42); ">#import </span>"NSNumber+code.h"</span></p><p style="margin-top: 0px; margin-bottom: 0px; font-family: Menlo; "><span style="font-size:10px;"><span style="color: #bb2ca2">@implementation</span> NSNumber (code)</span></p><p style="margin-top: 0px; margin-bottom: 0px; font-family: Menlo; "><span style="font-size:10px;">-(<span style="color: #703daa">NSNumber</span> *) add:(<span style="color: #bb2ca2">double</span>) num</span></p><p style="margin-top: 0px; margin-bottom: 0px; font-family: Menlo; "><span style="font-size:10px;">{</span></p><p style="margin-top: 0px; margin-bottom: 0px; font-family: Menlo; color: rgb(61, 29, 129); "><span style="font-size:10px;"><span style="color: #000000">    </span><span style="color: #bb2ca2">return</span><span style="color: #000000"> [</span><span style="color: #703daa">NSNumber</span><span style="color: #000000"> </span>numberWithDouble<span style="color: #000000">:([</span><span style="color: #bb2ca2">self</span><span style="color: #000000"> </span>doubleValue<span style="color: #000000">] +num)];</span></span></p><p style="margin-top: 0px; margin-bottom: 0px; font-family: Menlo; "><span style="font-size:10px;">}</span></p><p style="margin-top: 0px; margin-bottom: 0px; font-family: Menlo; "><span style="font-size:10px;">-(<span style="color: #703daa">NSNumber</span> *) mult:(<span style="color: #bb2ca2">double</span>) num</span></p><p style="margin-top: 0px; margin-bottom: 0px; font-family: Menlo; "><span style="font-size:10px;">{</span></p><p style="margin-top: 0px; margin-bottom: 0px; font-family: Menlo; color: rgb(61, 29, 129); "><span style="font-size:10px;"><span style="color: #000000">    </span><span style="color: #bb2ca2">return</span><span style="color: #000000"> [</span><span style="color: #703daa">NSNumber</span><span style="color: #000000"> </span>numberWithDouble<span style="color: #000000">:([</span><span style="color: #bb2ca2">self</span><span style="color: #000000"> </span>doubleValue<span style="color: #000000">] +num)];</span></span></p><p style="margin-top: 0px; margin-bottom: 0px; font-family: Menlo; "><span style="font-size:10px;">}</span></p><p style="margin-top: 0px; margin-bottom: 0px; font-family: Menlo; color: rgb(187, 44, 162); "><span style="font-size:10px;">@end</span></p>

所有NSNumber类的实例就都会具有add:、multi:方法,从而实现对NSNumber类的动态扩展。

我们知道,如果一个函数在.h文件中无声明而在.m文件中定义它的实现,那么该方法就是私有方法,只能在本类的文件中使用。若我们在类别的借口部分声明这个方法,那么我们就可以实现对该私有方法的访问。

—————————————————————————————————————————————————————————————————————————————

扩展(extension)

扩展与类别相似,扩展相当于匿名类别,即没有类别名得类别

类别,接口部分的定义,通常该文件命名为已有"类_xxx.h"
@interface 已有类 ()
//.......方法实现
@end

在用法上,类别通常都都有单独的.h和.m文件。扩展则是临时的对某个类进行扩展,类的实现部分同时实现类接口部分定义的方法和扩展中定义的方法。定义类的扩展时,可以增加额外的实例变量,也可使用@property和@synthesize关键字,但在定义类的额外列表时不允许额外定义实例变量。

有类名为Vehicle,只有name属性没有定义方法。对其进行扩展

#import "vehicle.h"
@interface Vehicle ()
@property(nonatomic, strong) NSString *color;
-(void) drive:(NSString *)name;
@end

为原来的Vehicle类增加color属性和drive:方法,因此在Vehicle.m实现文件里面要实现Vehicle.h里声明的方法及这个drive:方法。

//"Vehicle.m"
#import "Vehicle_ext.h"
@implementation Vehicle
-(void) drive:(NSString *)name
{
    NSLog(@"交通工具名称%@,颜色属性%@",_name,_color);
}
@end

在实际使用中,通用的做法是省略掉Vehicle_ext.h文件,而是将其中的内容直接添加在Vehicle.m文件@implementation前部即可。

—————————————————————————————————————————————————————————————————————————————

协议(protocol)

以NSObject为基础,为NSOject创建类别,创建类别时指定该类新增的方法,既可以实现非正式协议。而OC中对于实现非正式协议的类而言,OC并不强制实现该协议中的所有方法 。

正式协议使用@protocol关键字定义

@protocol 协议名 <父协议1, 父协议2>
{
      //.....方法声明
}
@end

协议是支持多继承的。在OC2.0标准中新增了@required\@optional两个关键字,声明方式是必须是必须实现还是可选的,默认为@required.

遵守协议的语法如下

@interface 类名:父类型 <协议1, 协议2...>

使用协议来定义变量,那么这些变量只能调用该协议中声明的方法,否则编译器会提示错误。

使用协议来定义变量的两种语法

NSObject<协议1,协议2..>*变量名;
id<协议1,协议2...> 变量;

协议体现的是一种规范,定义协议的类可以把协议定义的方法委托(delegate)给实现协议的类,这样可以让类具有更好的通用性,具体的动作交给协议的实现类来完成。在大量的应用程序开发中大量依赖委托这个概念。

时间: 2024-12-15 10:14:25

OC中类别、扩展、协议与委托的相关文章

oc中分类 扩展 协议的使用及区别

一.分类 1.适用范围 当你已经封装好了一个类(也可能是系统类.第三方库),不想在改动这个类了,可是随着程序功能的增加需要在类中增加一个方法,这时我们不必修改主类,只需要给你原来的类增加一个分类. 将一个大型的类拆分成不同的分类,在不同分类中实现类别声明的方法,这样可以将一个类的实现写到多个.m文件中,方便管理和协同开发. 分类中的方法可以只声明,不实现,所以在协议不支持可选方法的时候(协议现在已经支持可选方法),通常把分类作为非正式协议使用. 2.语法格式 文件中的语法 @interface

【IOS 开发】Object - C 面向对象高级特性 - 包装类 | 类处理 | 类别 | 扩展 | 协议 | 委托 | 异常处理 | 反射

一. Object-C 对象简单处理 1. 包装类 (1) 包装类简介 NSValue 和 NSNumber : -- 通用包装类 NSValue : NSValue 包装单个 short, int, long, float, char, id, 指针 等数据; -- NSNumber 包装类 : 用于包装 C 语言数据类型; NSNumber 方法 : -- "+ numberWithXxx :" : 将特定类型的值包装成 NSNumber; -- "- initWithX

oc中相关http协议知识

http协议 http协议是可靠的数据传输协议,不会被破坏或产生混乱 浏览网页时,浏览器会向服务器发送一条http请求,服务器会去寻找所期望的对象,若成功,则将对象,对象类型,对象长度等信息发送给客户端. URI(uniform resource identifier,统一资源标识符)(位移标识并定位信息资源) http解析对象的形式: |URL:统一资源定位符(几乎所有的uri都是url) |标准格式:方案+服务器的因特网地址+web服务器上得具体资源 如:http://www.joes-ha

OC中协议的概念以及用法

OC中协议的概念以及用法,协议也是OC中的一个重点,Foundation框架以及我们后面在写代码都会用到. OC中的协议就是相当于Java中的接口(抽象类),只不过OC中的名字更形象点,因为我们在学习Java中的接口时候,看可以知道其实接口就相当于一种契约(协议),给他的实现类打上标记了,当然这个活在Java5.0之后,被注解替代了,因为注解就是为了此功能诞生的.协议就是定义了一组方法,然后让其他类去实现 下面来看代码:WithProtocol.h[objc]  view plaincopy 

OC学习篇之---协议的概念和用法

这一篇文章我们在来看一下OC中协议的概念以及用法,协议也是OC中的一个重点,Foundation框架以及我们后面在写代码都会用到. OC中的协议就是相当于Java中的接口(抽象类),只不过OC中的名字更形象点,因为我们在学习Java中的接口时候,看可以知道其实接口就相当于一种契约(协议),给他的实现类打上标记了,当然这个活在Java5.0之后,被注解替代了,因为注解就是为了此功能诞生的. 协议就是定义了一组方法,然后让其他类去实现 下面来看代码: WithProtocol.h [objc] vi

(转载)OC学习篇之---协议的概念和用法

在前一篇文章中我们介绍了OC中类的延展,这一篇文章我们在来看一下OC中协议的概念以及用法,协议也是OC中的一个重点,Foundation框架以及我们后面在写代码都会用到. OC中的协议就是相当于Java中的接口(抽象类),只不过OC中的名字更形象点,因为我们在学习Java中的接口时候,看可以知道其实接口就相当于一种契约(协议),给他的实现类打上标记了,当然这个活在Java5.0之后,被注解替代了,因为注解就是为了此功能诞生的. 协议就是定义了一组方法,然后让其他类去实现. 下面来看代码: Wit

OC中保存自定义类型对象的持久化方法

OC中如果要将自定义类型的对象保存到文件中,必须进行以下三个条件: 想要把存放自定义类型的数组进行 持久化(就是将内存中的临时数据以文件<数据库等>的形式写到磁盘上)必须满足: 1. 自定义对象必须要序列化(将数据有序的存放) 2. 需要使用归档来进行持久化 3. 如果要加载持久化文件需要进行反序列化(就是将有序存放的数据读取并变成自定义对象) 第一要将自定义类型序列化以及第三步并将文件反序列化必须实现OC中的  <NSCoding>协议. 以Student类为例 @interfa

OC中SEL,类别,继承,协议的使用

1.SEL SEL是selector的缩写,selector在OC中作用是定义一个方法变量,通过该方法变量来调用方法.我们在后面的UI中会经常用selector来调用事件方法.下面我将举两个例子来说明SEL的使用. 直接通过方法名来调用,我们先新建一个Student类,并在其中定义一个名叫Test的对象方法.并定义一个输出语句: -(void)test { NSLog(@"这是SEL的测试方法"); } 我们在Main方法中通过SEL调用就会输出以上结果,如下: SEL s = @se

OC中的类别Category-协议Protocol-… - 韩俊强的博客 - 博客频道 - CSDN.NET

OC中的类别Category-协议Protocol- 类别(category)--通过使用类别,我们可以动态地为现有的类添加新方法,而且可以将类定义模块化地分不到多个相关文件中.通常只在类别中定义方法. 类别,接口部分的定义,通常该文件命名为已有"类+类别名.h" @interface 已有类 (类别名) //.......方法实现 @end #import #import "Buy.h" @interface Person : NSObject <<s