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名直接访问对象的属性,或者给对象的属性赋值.而不需 ...
随机推荐
- Spring各jar包的作用(转载)
spring.jar是包含有完整发布的单个jar 包,spring.jar中包含除了spring-mock.jar里所包含的内容外其它所有jar包的内容,因为只有在开发环境下才会用到 spring-m ...
- Spring4整合Hibernate4
首先,要明确Spring整合Hibernate可以做什么? 答案是: 1.由IOC容器来管理Hibernate的SessionFactory 2.让Hibernate使用上Spring的声明式事务 整 ...
- geusture for chrome cfg
{ "name": "Chrome Gestures", "version": "1.13.4", "norm ...
- oracle 11g在安装过程中出现监听程序未启动或数据库服务未注册到该监听程序
15511477451 原文 oracle 11g在安装过程中出现监听程序未启动或数据库服务未注册到该监听程序? 环境:win7 64位系统.oracle11g数据库 问题描述:在win7 64位系统 ...
- 连接Excel文件时,未在本地计算机上注册“Microsoft.Jet.OLEDB.4.0”提供程序
问题与解决 未在本地计算机上注册“Microsoft.Jet.OLEDB.4.0”提供程序 错误. string strCon = " Provider = Microsoft.Jet.OL ...
- java web 学习十二(session)
一.Session简单介绍 在WEB开发中,服务器可以为每个用户浏览器创建一个会话对象(session对象),注意:一个浏览器独占一个session对象(默认情况下).因此,在需要保存用户数据时,服务 ...
- codeforces 700B Connecting Universities 贪心dfs
分析:这个题一眼看上去很难,但是正着做不行,我们换个角度:考虑每条边的贡献 因为是一棵树,所以一条边把树分成两个集合,假如左边有x个学校,右边有y个学校 贪心地想,让每条边在学校的路径上最多,所以贡献 ...
- 《Python 学习手册4th》 第十四章 迭代器和解析
''' 时间: 9月5日 - 9月30日 要求: 1. 书本内容总结归纳,整理在博客园笔记上传 2. 完成所有课后习题 注:“#” 后加的是备注内容 (每天看42页内容,可以保证月底看完此书) “重点 ...
- 为什么你写的Python运行的那么慢呢?
大约在一年前,也就是2013年在Waza(地名),Alex Gaynor提到了一个很好的话题:为什么用Python.Ruby和Javascript写的程序总是运行的很慢呢?正如他强调的,关键就是现在出 ...
- WinDriver&PCIE
1.安装VS2012 安装VS2012略过,主要用它来做数据传输应用程序的,WINDRIVER提供了一系列API接口,方便了用户,使用户能直接进入用户态的编程,因为内核态的编程它已做好,不需要进行修改 ...