在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. BI Publisher(rtf)模板开发语法大全

    Rtf模板开发例如背景,纹理分栏等等功能都能用word工具实现不再具体总结大家可以参考word教程.....   一.组 定义一个组的目的是告诉XMLPublisher对重复的数据行进行循环显示,也就 ...

  2. android 网络工具 之Android-Volley的demo

    1.今天详细的研究了Volley的使用,下面来给大家介绍一下: Android Volley 是Google开发的一个网络lib,可以让你更加简单并且快速的访问网络数据.Volley库的网络请求都是异 ...

  3. 使用反射创建Bean、Spring中是如何根据类名配置创建Bean实例、Java提供了Class类获取类别的字段和方法,包括构造方法

    Java提供了Class类,可以通过编程方式获取类别的字段和方法,包括构造方法    获取Class类实例的方法:   类名.class   实例名.getClass()   Class.forNam ...

  4. java详解final、多态、抽象类、接口原理

    1:final关键字(掌握) (1)是最终的意思,可以修饰类,方法,变量. (2)特点: A:它修饰的类,不能被继承. B:它修饰的方法,不能被重写. C:它修饰的变量,是一个常量. (3)面试相关: ...

  5. SSH网上商城---商品详情页的制作

    在前面的博文中,小编分别简单的介绍了邮件的发送以及邮件的激活,逛淘宝的小伙伴都有这样的体会,比如在搜索框中输入连衣裙这个商品的时候,会出现多种多样各种款式的连衣裙,连衣裙的信息包括价格,多少人购买,商 ...

  6. [ExtJS5学习笔记]第十八节 Extjs5的panel的dockeditems属性配置toolbar

    本文地址:http://blog.csdn.net/sushengmiyan/article/details/39156321 官方例子:http://docs.sencha.com/extjs/5. ...

  7. iOS开发之*.a静态库注意事项

    以*.a静态库的形式引入工程的(比如:libUploadLib.a),*.a里面的class有category形式实现时,除了在工程Target的 Build Phases里面的 Link Binar ...

  8. 【Netty源码学习】入门示例

    Netty是由JBOSS提供的一个java开源框架.Netty提供异步的.事件驱动的网络应用程序框架和工具,用以快速开发高性能.高可靠性的网络服务器和客户端程序.        也就是说,Netty ...

  9. .NET 连接SQL Server2012遇到的连接出错问题解析

    最近在用VS2013编写相关于SQL Server数据库的代码,但是却遇到了艰难的bug问题,那就是在进行连接的时候出现了各种异常. 出错分析 1.首先应该想到的是数据库的相关服务没有开启. 因为默认 ...

  10. 【Unity Tips】备忘录(扫盲篇)

    写在前面 Unity3D虽然是个非常方便的游戏引擎,但还是有一些地方会产生一些让人莫名其妙的问题,而且debug半天也不知道到底哪里错了.往往在经过了大量的log之后,也许我们才顿悟,原来Unity内 ...