在Objective-C语言中, 类别、类扩展(也称为匿名类别)以及协议是Objective-C 语言级别支持的模式,用来实现对类进行功能扩展。

一、类别--用来增加方法到已存在类

声明一个类别的语法如下:

@interface ClassName (CategoryName)

@end

Objective-C 的标准的类声明,也使用@interface 关键字。但类别与类声明区别的是在括号中声明了一个类别名字。

类别能为任何类添加类别,包括不知道源代码的类(例如标准的Cocoa Touch 类等)。

已声明类别的类,类及其子类的所有实例都可以使用声明在类别中的方法,在运行时,通过类别为类添加的方法与类本身的方法没有任何区别。

类别也通常在头文件中进行声明,在分离的源文件中进行类别方法的实现。

为了使用为类添加的类别,需要在使用的地方输入声明类别的头文件。

类别可以作为一种设计模式使用,用来使用类别把一个实现复杂的类分离为几个实现文件。也可以为不同的平台提供不同的类别实现方法。

类别用来声明实例方法或类方法,但不适合声明额外的属性。

在一个类别接口中声明一个属性是有效的,但在类别中声明一个额外的实例变量是不可能的,这意味者编译器不能够生成任何实例变量,也不能够生成任何属性存取方法。
但你能够在类别实现中实现自己的属性存取方法,但你不能够保持和跟踪一个属性值,除非它已经在原先的类中存储。

另外需要注意的是类别中定义的方法名字不能与该类已有的方法或为该类(或其超类)定义的其它类别中的方法冲突。

为已存在类添加带有实例变量的属性的仅有的方法是使用类扩展。

二、类扩展--用来扩展一个类的内部实现

类扩展功能上与类别类似,用来扩展一个类的功能,与类别不同的是,类扩展中能为一个类增加属性和实例变量。另外类扩展仅能在一个有源码的类中使用,用来为其添加功能。使用类扩展通常用来实现和扩展类的私有信息(包括私有属性和方法)。

声明一个类扩展的语法与类别的语法相似,但括号中名字为空,因此类扩展也被称为匿名类别。如下所示:

@interface ClassName ()

@end

类扩展中声明的方法要在原先类的@implementation块中加以实现。

如果在一个类扩展中声明一个属性,编译器自动为其生成相对应的存取方法和一个实例变量。如果在一个类扩展中增加任意方法,它们也必须在类的实现中加以实现。

在一个类扩展中添加定制的实例变量也是可能的。

三、协议

在Objective-C中,每个类都都对外提供自己的接口,类包括接口声明和类实现。而没有像其它语言(如java)那样,接口与类定义是独立的,一个类可以实现多个接口。

但在Objective-C中协议可以起到类似的作用,协议用来声明与任何特定的类独立的方法,如果一个类声明符合某种协议,则其实现中必须实现协议中声明的方法,但与其它语言接口定义不同的是在协议中不仅能声明对象方法,还能声明类方法以及属性。

定义一个协议的语法如下:

@protocol ProtocolName

// list of methods and properties

@end

Objective-C 使用三角括号指示一个属性或类符合一种协议。

默认情况下在一个协议中声明的方法都是必须方法,任何符合该协议的类必须实现这些方法。

在协议中也可以使用@optional关键字规定可选方法。遵从包括可选方法的协议的类可以根据需要实现可选方法或不实现。

@protocol XYZPieChartViewDataSource

- (NSUInteger)numberOfSegments;

- (CGFloat)sizeOfSegmentAtIndex:(NSUInteger)segmentIndex;

@optional

- (NSString *)titleForSegmentAtIndex:(NSUInteger)segmentIndex;

- (BOOL)shouldExplodeSegmentAtIndex:(NSUInteger)segmentIndex;

@required

- (UIColor *)colorForSegmentAtIndex:(NSUInteger)segmentIndex;

@end

在以上协议声明中的titleForSegmentAtIndex:和shouldExplodeSegmentAtIndex:方法标记为是可选方法。

@optional关键字指示其下面声明的方法都是可选方法,直到协议定义结束或碰到另外的@required指令。

如果在一个协议中标记一个方法为可选,你必须在试图调用它之前检查是否一个对象实现了该方法。

使用respondsToSelector: 方法使用一个@selector指令引用一个方法的标识(方法名)来检查该方法是否实现。如下所示:

NSString *thisSegmentTitle;

if ([self.dataSource respondsToSelector:@selector(titleForSegmentAtIndex:)]) {

thisSegmentTitle = [self.dataSource titleForSegmentAtIndex:index];

}

也可以规定一个协议符合另外的协议,语法如下:

@protocol MyProtocol <NSObject>

...

@end

声明一个类符合一个协议的语法如下:

@interface MyClass : NSObject <MyProtocol>

...

@end

与其它语言一个类可以实现多个接口相同,在Objective-C也可以声明一个类符合多个协议,语法如下:

@interface MyClass : NSObject <MyProtocol, AnotherProtocol, YetAnotherProtocol>

...

@end

但如果出现这种情况,意味着你的类过于复杂,需要重构,分离相关的行为到多个较小的类,每一个类定义清楚的责任。

Objective-C的面向对象特性(二)的更多相关文章

  1. TypeScript入门知识五(面向对象特性二)

    1.泛型(generic) 参数化的类型,一般用来限制集合的内容 class Person { constructor(private name: string) { } work() { }}var ...

  2. 浅谈Objective—C中的面向对象特性

    Objective-C世界中的面向对象程序设计 面向对象称程序设计可能是现在最常用的程序设计模式.如何开发实际的程序是存在两个派系的-- 面向对象语言--在过去的几十年中,很多的面向对象语言被发明出来 ...

  3. Python 基础 面向对象之二 三大特性

    Python 基础 面向对象之二 三大特性 上一篇主要介绍了Python中,面向对象的类和对象的定义及实例的简单应用,本篇继续接着上篇来谈,在这一篇中我们重点要谈及的内容有:Python 类的成员.成 ...

  4. Javascript面向对象特性实现封装、继承、接口详细案例——进级高手篇

    Javascript面向对象特性实现(封装.继承.接口) Javascript作为弱类型语言,和Java.php等服务端脚本语言相比,拥有极强的灵活性.对于小型的web需求,在编写javascript ...

  5. javascript进阶——面向对象特性

    面向对象的javascript是这门语言被设计出来时就考虑的问题,熟悉OOP编程的概念后,学习不同的语言都会发现不同语言的实现是不同的,javascript的面向对象特性与其他具有面向对象特性的语言的 ...

  6. .NET面向对象特性之封装

    .NET面向对象特性之封装 面向对象的基本内容由:类.对象.属性.方法.字段构成. 面向对象的三大特性:继承.多态.封装. 关于面向对象的特性很多人都把目光转向了继承.多态和接口,却很少有人提及过封装 ...

  7. .NET面向对象特性之多态

    .NET面向对象特性之多态 前言 上一篇总结了面向对象三大特性之一的继承,再接再厉,这一章继续总结多态.同时把继承中涉及到多态的内容进一步补充扩展.可以说“继承”是多态的根基.但继承主要关注的是“共通 ...

  8. .NET面向对象特性之“继承”

    整体简介 1.理解继承——继承关系图 2.实现继承与接口多继承 3.new. virtual.override方法 4.抽象方法和抽象类的继承 5.继承的本质 6.继承的复用性.扩展性和安全性 7.多 ...

  9. TypeScript -- 面向对象特性

    .class关键字和类名就可以定义一个类 . 类的访问控制符--有三个,.] = ] = ] = ;.声明参数 .用接口声明方法 .理解模块--一个文件就是一个模块,就是这么个意思 ,不用想的多么高大 ...

  10. 【游戏开发】在Lua中实现面向对象特性——模拟类、继承、多态

    一.简介 Lua是一门非常强大.非常灵活的脚本语言,自它从发明以来,无数的游戏使用了Lua作为开发语言.但是作为一款脚本语言,Lua也有着自己的不足,那就是它本身并没有提供面向对象的特性,而游戏开发是 ...

随机推荐

  1. Android状态栏透明(沉浸式效果)

    Android状态栏透明(沉浸式效果) 默认效果 沉浸式效果 方式一 源码 下载地址(Android Studio工程):http://download.csdn.net/detail/q487880 ...

  2. 详解EBS接口开发之供应商导入补充-供应商地点增加实例

    DECLARE --v_org_id number; v_vendor_interface_id NUMBER; v_vendor_site_interface_id NUMBER; --接口表的id ...

  3. 剑指Offer——腾讯+360+搜狗校招笔试题+知识点总结

    剑指Offer--腾讯+360+搜狗校招笔试题+知识点总结 9.11晚7:00,腾讯笔试.选择题与编程.设计题单独计时. 栈是不是顺序存储的线性结构啊? 首先弄明白两个概念:存储结构和逻辑结构. 数据 ...

  4. Android存储之SharedPreferences

    Android数据存储之SharedPreferences SharedPreferences对象初始化 SharedPreferences mSharedPreferences = getShare ...

  5. Shell在大数据时代的魅力:从一道百度大数据面试题想到的点滴

    对于在Linux下开发的同学来说,Shell可以说是一种基本功. 对于运维的同学来说,Shell可以说是一种必备的技能,而且应该要非常熟练的书写Shell.对于Release Team,软件配置管理的 ...

  6. sql中奇怪的sum(1),sum(2),count(1),count(6),count(*):统计总数

    sql的统计函数 sql统计函数有 count 统计条数,配合group用 sum 累加指定字段数值 但注意sum(1)就特殊 sum(1)等同于count(*) sum(1)统计个数,功能和coun ...

  7. 【IOS 开发】Object - C 数组使用详解

    . 一. 一维数组 1. 一维数组定义 (1) 数组定义 数组定义格式 : type arrayName[len]; -- 默认初始化 : 注意 数组定以后, 如果是 int 数组默认初始化为 0, ...

  8. 【一天一道LeetCode】#108. Convert Sorted Array to Binary Search Tree

    一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 Given a ...

  9. iOS中 超简单抽屉效果(MMDrawerController)的实现

    ios开发中,展示类应用通常要用到抽屉效果,由于项目需要,本人找到一个demo,缩减掉一些不常用的功能,整理出一个较短的实例. 首先需要给工程添加第三方类库 MMDrawerController: 这 ...

  10. pig中查询top k,返回每个hour和ad_network_id下最大两个记录(SUBSTRING,order,COUNT_STAR,limit)

    pig里面是有TOP函数,不知道为什么用不了.有时间要去看看pig源码了. SET job.name 'top_k'; SET job.priority HIGH; --REGISTER piggyb ...