iOS开发笔记系列-基础5(分类和协议)
分类
在Objective-C中,除了通过新建子类的方式来向类添加新方法外,还可以通过分类的方式。分类提供了一种简单的方式,将类的定义模块化到相关方法的组或分类中,它还提供了扩展现有类定义的简便方式,并且不需要访问类的源代码,也无须创建子类。
比如:
//SomeClass+MathOps.h
#import "SomeClass.h"
@interface SomeClass (MathOPs)
-(SomeClass *) add: (SomeClass *)s;
-(SomeClass *) sub: (SomeClass *)s;
-(SomeClass *) div: (SomeClass *)s;
-(SomeClass *) mul: (SomeClass *)s;
@end
这里不用列出父类,也不用向编译器告知实例变量,因为从import的文件的接口部分已经这样做了。
可以将所有的方法的定义放在一个实现部分。也就是说,可以在一个实现文件中定义SomeClass.h接口部分中的所有方法,以及MathOps分类中的所有方法。或者,在单独的实现部分定义分类的方法,这种情况下,这些方法的实现部分必须找出方法所属的分类。如@implementation SomeClass (MathOps) 这样。
如果将分类放到一个主类定义文件中,那么这个类的所有用户都将访问这个分类中的方法。如果不能直接修改原始的头文件,则只能将分类单独保存文件。
类的扩展
创建一个未命名的分类,且在()内不指定名字,这是一种特殊情况,这种特殊语法定义为类的扩展。定义一个像这样的未命名分类时,可以通过定义附加的实例变量来扩展类,这在命名的分类中是不允许的。未命名分类中声明的方法需要在主实现区域实现,而不是在分离的实现区域中实现。如果没有实现未命名分类的接口部分列出的全部方法,编译器会发出警告。
比如,在一个类的实现文件中:
//SomeClass.m
#import "SomeClass.h"
//类的扩展
@interface SomeClass ()
@property int pp;
-(void)someFunc;
@end //--------------------------
@implementation SomeClass
@synthesize pp;
.....
@end
通过添加一个新的实例变量和方法扩展了这个类,并合成了存取方法。
未命名分类是非常有用的,因为它们的方法都是私有的。如果需要写一个类,其数据和方法仅供类本身使用,未命名分类比较合适。
分类的注意事项:
分类可以覆写该类中的另一个方法,不过这是拙劣的设计,因为覆写一个方法之后,再也不能访问原来的方法。如果需要覆写,正确的选择是创建子类,子类中覆盖父类的方法,此时仍然可以通过super来调用父类原方法。
可以拥有许多分类,如果一个方法定义在多个分类中,该语句不会指定使用哪个分类。
通过分类添加新方法来扩展类不仅会影响这个类,同时也会影响它的所有子类。
协议
协议是多个类共享的一个方法列表,协议中列出的方法并没有相应的实现,计划由其他人来实现的。协议提供一种方式,用指定的名称定义一组多少有点相关的方法。这些方法有的是必须实现的(@required),有的是可选的(@optional)。
定义协议是使用@protocol指令,后面加上协议名称。
当采用某协议时,在@interface行最后的一对<>中列出协议名称即可,同时在实现部分至少实现协议的必须实现方法。
比如:@interface SomeClass:SuperClass <SomeProtocol>
协议是无类的,它不引用任何类,任何类都可以遵守某个协议。可以使用comformsToProtocol:方法检查一个对象是否遵循某协议。
代理
协议也是一种两个类之间的接口定义。定义了协议的类可以看做是将协议定义的方法代理给了实现它们的类,这样,类的定义可以更为通用,因为具体的动作由代理类来承担,来响应某些事件或者定义某些参数。Cocoa和iOS非常依赖代理这个概念。比如UITableView类,这个类不清楚表格的标题是什么,需要包含多少区块或是包含多少行,填充表格的内容是什么。所以,代理定义了一个UITableViewDataSource协议,如果它需要信息,比如表格中每个区块有多少行,它就会调用类中实现协议的相关方法。UITableView类还定义了其他的协议如UITableViewDelegate,协议还定义了一些方法,如表格某行被选中需要怎样,UITableView不知道要做什么,所以将这个代理给了实际用户。
非正式协议
非正式协议实际上是一个分类,列出了一组方法但是没有实现他们。每个人都继承相同的根对象,因此,非正式协议通常是为根类定义的。有时,非正式协议又被称为抽象协议。因为非正式协议本身不是协议而是分类,所以编译器不提供协议相关的帮助,不会存在遵守或者不遵守非正式协议或者由编译器测试这样的概念。
合成对象
除了通过派生子类和分类可以扩展类定义以外,还有一项技术可以定义一个类包含其他类的一个或多个对象,这个新类的对象就是合成对象,因为它是由其他对象组成的。
通过派生子类扩展父类,子类就集成了父类所有的实例变量和方法,一些情况下,有些方法并不适用于子类,然而子类的用户却有可能会访问它们。作为创建子类的替代方式,可以定义一个新类,它包含要扩展类的实例变量,然后,只需在新类中定义适合该类的方法。比如:
@interface NewClass:NSObject
{
SomeClass *s;
}
-(void)newFunc;
@end
这里需要注意,与子类扩展不同,子类版本允许直接访问父类的方法,这里NewClass的对象不能直接访问SomeClass的方法了,而是在自己的方法里比如newFUnc里边,通过实例变量s来访问那些可以被用到的方法。记住,这里在初始化时,需要覆写init或者自定义初始化方法来给s分配空间。
iOS开发笔记系列-基础5(分类和协议)的更多相关文章
- iOS开发笔记系列-基础1(数据类型与表达式)
学习iOS开发快两年了,去年完成MagViewer之后就因为公司的其他业务繁重,除了维护这个应用之外,只是断断续续地自己做一些实验开发,没有再发布新的应用,这里想整理一下学习过程中的笔记,以便加深印象 ...
- iOS开发笔记系列-基础2(类)
面向对象编程总是离不开类和对象的,Objective-C也不例外,不过Objective-C中的类还有一些自己的独特点. 类的声明和定义 在iOS开发中,类的声明与定义通常都是分开的,类得声明通常存放 ...
- iOS开发笔记系列-基础6(预处理程序)
预处理程序提供了一些工具,使用这些工具更易于开发.阅读.修改程序,也易于将程序移植到不同的系统中.又称为宏. #define #define语句的基本用途之一就是给富豪名称指定程序常量.比如: #de ...
- iOS开发笔记系列-基础3(多态、动态类型和动态绑定)
多态:相同的名称,不同的类 使不同的类共享相同方法名称的能力成为多态.它让你可以开发一组类,这组类中的每一个类都能响应相同的方法名.每个类的定义都封装了响应特定方法所需要的代码,这使得它独立于其他的类 ...
- iOS开发笔记系列-基础7(C语言特性)
Objective-C是C语言的扩展,因此,也具备很多C语言的基本特性,这里只罗列部分. 块(Blocks) 块是对C语言的一种扩展,它并未作为标准ANSI C所定义的部分,而是Apple添加到语言中 ...
- iOS开发笔记系列-基础4(变量与数据类型)
对象的初始化 对象的初始化方法一般都如下: -(id)init { self=[super init]; if(self){ ... } return self; } 这个方法首先会调用父类的初始化方 ...
- IOS科研IOS开发笔记学习基础知识
这篇文章是我的IOS学习笔记,他们是知识的基础,在这里,根据记录的查询后的条款. 1,UIScrollView能完毕滚动的功能. 示比例如以下: UIScrollView *tableScrollVi ...
- Winform开发框架之客户关系管理系统(CRM)的开发总结系列3-客户分类和配置管理实现
我在本系列随笔的开始,介绍了CRM系统一个重要的客户分类的展示界面,其中包含了从字典中加载分类.从已有数据中加载分类.以及分组列表中加载分类等方式的实现,以及可以动态对这些节点进行配置,实现客户分类的 ...
- iOS开发技巧系列---详解KVC(我告诉你KVC的一切)
KVC(Key-value coding)键值编码,单看这个名字可能不太好理解.其实翻译一下就很简单了,就是指iOS的开发中,可以允许开发者通过Key名直接访问对象的属性,或者给对象的属性赋值.而不需 ...
随机推荐
- ffmpeg显示视频
项目最近需要实现播放视频功能,这个在上家公司就做过.虽然跟之前的场景不一样,有以前的功底还是很快可以解决,事实也确实如此.在使用DShow处理完视频分割与合并后,继续使用DShow显示视频,很快即完成 ...
- MyBatis一对多双向关联——MyBatis学习笔记之七
处理has-one关系需要用到association元素,而处理has many关系则需要用到collection元素.例如本例中,假设一 名教师可同时指导多名学生,下面就来介绍如何使用collect ...
- list用法详解
在这里感谢大牛们的奉献!此致敬礼! 本文转载自百度文库.作者如下.其中下面的count, count_if等函数的使用有些陈旧,如在编译时遇到问题,请百度. 标准模板库(STL)介绍 作者:Scott ...
- linux命令——磁盘命令mkdir
一.介绍 mkdir 命令用于创建文件夹或目录(类似dos下的md命令),要求创建目录的用户在当前目录中具有写权限, 并且指定目录名不能是当前目录中已有的目录或文件名称.名称区分大小写. 二.用法及参 ...
- bjfu1235 两圆公共面积
给定两个圆,求其覆盖的面积,其实也就是求其公共面积(然后用两圆面积和减去此值即得最后结果). 我一开始是用计算几何的方法做的,结果始终不过.代码如下: /* * Author : ben */ #in ...
- 通过gdb跟踪Linux内核装载和启动可执行程序过程
作者:吴乐 山东师范大学 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 实验目的:通过对一个简单的可执 ...
- 安装nagios出现的两个错误记录
最近在安装nagios,出现几个错误记录: 一 检查nagios配置的时候出现错误如下: Warning: Duplicate definition found for host 'kelly' (c ...
- struts2中访问和添加Application、session以及request属性
一.访问或添加Application.session.request属性 <一>方式一 HelloWorldAction类中添加如下代码 //此方法适用于仅对Application.ses ...
- 第三百零一天 how can i 坚持
其实真搞不大懂自己.不喜欢巴结人,也不喜欢阿谀奉承,但老是感觉自己却又在那么做,是对自己要求太高了,想太多?? 郭娜好像把我拉黑了,拉黑就拉黑吧.或许真不合适. 睡觉.
- Apache Spark GraphX的特点
GraphX 的特点是离线计算.批量处理,基于同步的 BSP 模型(Bulk Synchronous Parallel Computing Model,整体同步并行计算模型),这样的优势在于可以提升数 ...