郝萌主倾心贡献。尊重作者的劳动成果,请勿转载。

假设文章对您有所帮助。欢迎给作者捐赠,支持郝萌主。捐赠数额任意,重在心意^_^

我要捐赠: 点击捐赠

Cocos2d-X源代码下载:点我传送

分类与协议是OC比較有特色的部分。

从表面来看,
分类呢有点类似抽象方法在抽象类中(C++或者Java里的那个抽象类概念)。

协议类似接口(Java语言那个接口),可是又不能“一视同仁”。

分类概念
分类(Category) 同意向一个类文件里加入新的方法声明, 
它不须要使用子类机制, 而且在类实现的文件里的同一个名字下定义这些方法。 
其语法举比例如以下: 
#import
"ClassName.h"

@interface ClassName ( CategoryName )

// 方法声明

@end
分类实例



上一篇多态性介绍中以前使用过Vector和Scalar的样例, 
以下我们为Vector添加“减”sub的方法。

Vector+sub.h文件
#import <Foundation/Foundation.h>
#import "Vector.h" @interface Vector (sub) -(Vector *) sub: (Vector *) v; @end
Vector+sub.m文件
#import "Vector+sub.h"

@implementation  Vector (sub) 

-(Vector *) sub: (Vector *) v {
Vector *result = [[Vector alloc] init];
[result setVec1: vec1 - [v vec1] andVec2: vec2 - [v vec2]];
return result;
} @end
调用的main函数
#import <Foundation/Foundation.h>
#import "Vector+sub.h" int main (int argc, const char * argv[]) { Vector *vecA =[[Vector alloc] init];
Vector *vecB =[[Vector alloc] init];
id result; //set the values
[vecA setVec1: 3.2 andVec2: 4.7];
[vecB setVec1: 32.2 andVec2: 47.7]; // print it
[vecA print];
NSLog(@" + ");
[vecB print];
NSLog(@" = ");
result = [vecA add: vecB];
[result print]; [vecA print];
NSLog(@" - ");
[vecB print];
NSLog(@" = ");
result = [vecA sub: vecB];
[result print]; // free memory
[vecA release];
[vecB release];
[result release];
return 0;
}
当中result = [vecA add: vecB] 中的add: 是Vector类原有的方法。 
result = [vecA sub: vecB] 中的sub: 是Vector分类加入的方法。



分类是在Java和C++等面向对象的语言中没有的概念, 
分类本质上是通过Objective-C的动态绑定而实现的。

通过分类使用可以达到比继承更好的效果。

从上面这个样例能够看到,分类提供了一种简单的方式。

用它能够将类的定义模块化到相关方法的组或分类中。

它还提供了扩展现有类定义的简便方式,而且不必訪问类的源码,也不须要创建子类。

#import "Fraction.h"

@interface Fraction (MathOps)

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

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

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

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

@end

注意,这既是接口部分的定义,也是现有接口部分的扩展。

因此。必须包含原接口部分,这样编译器就知道Fraction类。

依照惯例。作为分类的.h和.m文件的基本名称是由类的名称紧接着分类的名称。

比如:FractionMathOps.m;

一些程序猿使用符号“+”来分隔类和分类的名称,比方Fraction+MathOps.h。

只是不建议这样命名。

类的扩展:

创建一个未命名的分类。且在括号“()”之间不指定名字,这是一种特殊的情况。

这样的特殊的语法定义为类的扩展。

未命名类中声明的方法须要在主实现区域实现,而不是在分离的实现区域中实现。

未命名分类是很实用的,由于它们的方法都是私有的。

假设须要写一个类,并且数据和方法仅供这个类本身使用,未命名类比較合适。

关于分类的注意事项:

分类能够覆写该类中的还有一个方法,可是通常觉得这样的做法是做虐的设计习惯。所以须要注意:

第一、覆写了一个方法后。再也不能訪问原来的方法。(假设确实须要覆写方法。正确的选择可能是创建子类。)

第二、通过使用分类加入新的方法来扩展类不只影响这个类,同一时候也会影响它的全部子类。

第三、对象/分类命名对必须是唯一的。

由于大家使用的名称空间是程序代码、库、框架和插件共享的。


协议(Protocol ) 
与Java的Interface(接口 )或者C++的纯虚类同样,就是用来声明接口的。
协议仅仅是定义了方法的列表,协议不负责实现方法。目的是让别的类来实现。

以Graphics协议为例:
Graphics中定义了onDraw方法, 可是我们细致分析一下onDraw方法不能实现的。 
作为Graphics(几何图形)它无法知道它的子类怎样绘制图形。 
它仅仅能规定绘制图名字为onDraw签名和返回值等信息, 但不能给出详细的实现, 
因此Graphics(几何图形) 不应该设计成为类而应该设计成为协议。 



@protocol Graphics

-(void) onDraw;

@end

协议仅仅有接口部分, 没有实现部分, 所以没有m文件, keyword@protocol , 
协议能够继承别的协议, 协议中不能定义成员变量。

协议实现类Ellipse
#import <Foundation/Foundation.h>
#import "Graphics.h" @interface Ellipse:NSObject <Graphics> { } @end
#import "Ellipse.h"

@implementation Ellipse

-(void)onDraw {
NSLog(@"绘制椭圆形");
} @end
协议实现类Triangle
#import <Foundation/Foundation.h>
#import "Graphics.h" @interface Triangle:NSObject <Graphics> { } @end
#import "Triangle.h"

@implementation Triangle

-(void)onDraw {
NSLog(@"绘制三角形");
} @end
代码说明:
协议的实现是在类声明的父类之后, 加上<Graphics>,
与类的单个继承不同, 
协议能够实现多个, 表示要实现这个协议, 
假设有多个协议要实现用“,” 号分隔: <P1,P2>。

调用的main函数
#import <Foundation/Foundation.h>
#import "Graphics.h"
#import "Ellipse.h"
#import "Triangle.h" int main (int argc, const char * argv[]) { id graphics;
graphics = [[Ellipse alloc] init];
[graphics onDraw];
[graphics release]; graphics = [[Triangle alloc] init];
[graphics onDraw];
[graphics release]; return 0;
}

从上面的样例能够看出:

协议是多个类共享的一个方法列表。

协议中列出的方法没有对应的实现,计划由其它人来实现。

协议提供了一种方式。用指定的名称定义一组多少有点相关的方法。

假设决定实现特定协议的全部方法,也就意味着要遵守(confirm to)或採用(adopt)这项协议。

定义一个协议非常easy:仅仅要使用@protocol指令。然后跟上你给出的协议名称。

比如:

@protocol NSCoping

- (id) copyWithZone: (NSZone *) zone;

@end

这里再提到两个重要的协议:

NSCopying

NSCoding

假设你的类採用NSCopying协议,则必须实现copyWithZone:的方法

通过在@interface行的一对尖括号(<....>)内列出协议名称。能够告知编译器你正在採用的一个协议。

这项协议的名称放在类名和它的父类名称之后,

比如:

@interface AddressBook:NSObject <NSCoping>

假设你的类採用多项协议,仅仅需把它们都列在尖括号里,并用逗号分开。比如:

@interface AddressBook:NSObject <NSCoping, NSCoding>

假设你定义了自己的协议,那么不必由自己实现它。

假设一个类遵守NSCoping协议。则它的子类也遵守NSCoping协议

(只是并不意味着对该子类而言。这些方法得到了正确的实现)。

@required和@optionalkeyword


@protocol MyProtocol

- (void) requiredMethod;

@optional

- (void) anOptionalMethod;

- (void) anotherOptionalMethod;

@required

- (void) anotherRequiredMethod;

@end

注意。这里使用了@optional指令。

该指令之后列出的全部方法都是可选的。

@required指令之后的是须要的方法。


注意,协议不引用不论什么类,它是无类的(classless)。

不论什么类都能够遵循MyProtocol协议。

能够使用conformsToProtocol:方法检查一个对象是否遵循某些协议。

比如:

if ([currentObject conformsToProtocol: @protocol (MyProtocol)] == YES) {

...

}

这里使用的专用@protocol指令用于获取一个协议名称,并产生一个Protocol对象。

conformsToProtocol:方法期望这个对象作为它的參数。

通过在类型名称之后的尖括号里加入协议名称。能够借助编译器来检查变量的一致性。

比如:

id <Drawing> currentObject;

这告知编译器currentObject将包括遵守Drawing协议的对象。

假设这个变量保存的对象遵守多项协议,则能够列出多项协议 ,

例如以下面代码:

id <NSCoping, NSCoding> myDocument;

定义一项协议时。能够扩展现有协议的定义。

如:

@protocol Drawing3D <Drawing> Drawing3D 协议也採用了Drawing协议。

最后要说的是。分类也是能够採用一项协议。

和类名一样,协议名必须是唯一的。

代理:

协议也是一种两个类之间的接口定义。

定义了协议的类能够看做是将协议定义的方法代理给了实现它们的类。

非正式(informal)协议:是一个分类,列出了一组方法但并没有实现它们。

因此,非正式分类一般是为根类定义的。有时,非正式协议也称为抽象(abstract)协议。

非正式协议实际上仅仅是一个名称下的一组方法。

声明非正式协议的类自己并不实现这些方法。

而且选择实现这些方法中的子类须要在它的接口部分又一次声明这些方法。

同一时候还要实现这些方法中的一个或多个。

注意:前面描写叙述的@optional指令加入到了Objective-C 2.0语言中,用于代替非正式协议的使用。

合成对象:

能够定义一个类包括其它类的一个或多个对象。

这个新类的对象就是所谓的合成(composite)对象,由于它是由其它对象组成的。

子类依赖于父类。改变了父类有可能会使得子类中的方方法不起作用。

版权声明:本文博客原创文章,博客,未经同意,不得转载。

Objective-C马路成魔【12-分类和协议】的更多相关文章

  1. Objective-C马路成魔【14-关键C语言功能】

    郝萌主倾心贡献,尊重作者的劳动成果,请勿转载. 假设文章对您有所帮助,欢迎给作者捐赠,支持郝萌主.捐赠数额任意,重在心意^_^ 我要捐赠: 点击捐赠 Cocos2d-X源代码下载:点我传送 这里介绍一 ...

  2. 成魔笔记1——先入IT,再成魔

    关于我为什么要写这个博客的原因,做一个简单的解释.因为报考的一时兴起,我选择了软件专业.可是三年下来,感觉自己没做多少事,也没收获到多少东西.很多时候都是老师讲什么,都是完全陌生的东西,跟不上教学的思 ...

  3. Objective-C之成魔之路【0-序章】

    郝萌主倾心贡献,尊重作者的劳动成果.请勿转载. 假设文章对您有所帮助.欢迎给作者捐赠,支持郝萌主,捐赠数额任意.重在心意^_^ 我要捐赠: 点击捐赠 Cocos2d-X源代码下载:点我传送 C语言首创 ...

  4. 第12讲 | TCP协议(下):西行必定多妖孽,恒心智慧消磨难

    第12讲 | TCP协议(下):西行必定多妖孽,恒心智慧消磨难 如何做个靠谱的人? 有问有答,任务发送和接收有记录,完成有反馈. 如何实现一个靠谱的协议? TCP 协议使用的也是同样的模式.为了保证顺 ...

  5. 机器学习入门12 - 分类 (Classification)

    原文链接:https://developers.google.com/machine-learning/crash-course/classification/ 1- 指定阈值 为了将逻辑回归值映射到 ...

  6. Objective-C之成魔之路【5-选择结构】

    郝萌主倾心贡献.尊重作者的劳动成果,请勿转载. 假设文章对您有所帮助,欢迎给作者捐赠,支持郝萌主.捐赠数额任意,重在心意^_^ 我要捐赠: 点击捐赠 Cocos2d-X源代码下载:点我传送 Objec ...

  7. Objective-C之成魔之路【16-使用文件】

    郝萌主倾心贡献,尊重作者的劳动成果.请勿转载. 假设文章对您有所帮助,欢迎给作者捐赠.支持郝萌主,捐赠数额任意.重在心意^_^ 我要捐赠: 点击捐赠 Cocos2d-X源代码下载:点我传送 语言的设计 ...

  8. Objective-C之成魔之路【9-类构造方法和成员变量作用域、以及变量】

    郝萌主倾心贡献,尊重作者的劳动成果.请勿转载. 假设文章对您有所帮助,欢迎给作者捐赠,支持郝萌主,捐赠数额任意,重在心意^_^ 我要捐赠: 点击捐赠 Cocos2d-X源代码下载:点我传送 构造方法 ...

  9. 将decimal类型的数据转成2.12这样价钱的显示方式

    UnitPrice = string.Format("{0:.00}", m.UnitPrice),

随机推荐

  1. Oracle trunc()函数

    Oracle trunc()函数的用法   --Oracle trunc()函数的用法/**************日期********************/1.select trunc(sysd ...

  2. CAS Spring Security 3 整合配置(转)

    一般来说, Web 应用的安全性包括用户认证( Authentication )和用户授权( Authorization )两个部分.用户认证指的是验证某个用户是否为系统中的合法主体,也就是说用户能否 ...

  3. 在linux上创建nfs遇到的问题。

    我们部署程序时,图片server是单独的一台server,有自己独立的域名.而应用部署在还有一台server上,我们使用一些附件上传工具.比方ajaxfileupload上传附件时是无法跨域訪问的. ...

  4. json学习初体验--第三者jar包实现bean、List、map创json格式

    1.的需要jar包裹json-lib.jar 下载链接: http://sourceforge.net/projects/json-lib/files/json-lib/ 此包还须要下面的依赖包, c ...

  5. 【转】HLSL基础

    原文地址http://blog.csdn.net/chpdirect1984/article/details/1911622 目录 前言 1.HLSL入门 1.1什么是着色器 1.2什么是HLSL 1 ...

  6. cocos2dX 它CCScene创建原则和切换模式

    今天, 让我们来看看现场CCScene创建原则和切换模式, 首先, 个什么样子: 我们先来看看效果: 啥也没有: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZX ...

  7. 【Java收集的源代码分析】Hashtable源代码分析

    Hashtable简单介绍 Hashtable相同是基于哈希表实现的,相同每一个元素是一个key-value对,其内部也是通过单链表解决冲突问题,容量不足(超过了阀值)时.相同会自己主动增长. Has ...

  8. MonkeyRunner源代码分析Android通信设备

    正如前面<谁动了我的截图?--Monkeyrunner takeSnapshot方法源代码跟踪分析>所述,本文主要会尝试描写叙述android的自己主动化測试框架MonkeyRunner到 ...

  9. AWS发布架构师认证的专业解决方案

    完成Amazon EC2初始化几个例子就足够了,那么证明你的AWS建筑学专业技术需要长时间使用如何?AWS专业建筑师认证新颖的解决方案出炉! 2013年4月,AWS正式启动AWS认证计划,同时发布AW ...

  10. 基本数据类型TypeScript

    TypeScript 前言 最近项目很急,所以没有什么时间回答关于Xamarin.Android方面的问题,也有一段时间没有更新.主要是手头很缺人,如果有谁有兴趣加入我们的话,可以私聊我,这样我就能继 ...