OC学习7——类别、扩展和协议
1、我么在调用NSLog()方法打印一个对象时,实际上是调用了该对象的description方法,这个description方法就和Java中的toString()方法一样。所以,下面两行代码其实是一样的
NSLog(@"%@", p) ; NSLog(@"%@", [p description]) ;
description方法是NSObject类的一个实例方法,所有的OC都是NSObject类的子类,因此,所有的类都有description方法。description方法方法通常用于实现这样的一个功能:当程序员直接打印该对象时,系统将会输出该对象的“自我描述”信息,用以告诉外界该对象具有的状态信息。NSObject类提供的description方法总是返回<FKPerson:十六进制的首地址>,这个返回值并不是先自我描述的功能,因此,如果用户需要自定义类实现自我描述的功能,则必须重写NSObject类的description方法。
2、==与isEqual()方法的区别(这一点与Java中的异同点是一致的):
- ==:如果是比较对象是两个基本类型,则数值相同就返回true,不同则返回false。如果比较对象是两个指针变量,则如果两个指针都指向同一个对象则返回true,否则返回false。
- isEqual():该方法是NSObject类提供的一个实例方法,因此所有指针变量都可以调用这个方法来判断是否与其他指针变量相等。在默认情况下,isEqual()的判断方法和==一样。如果希望采用自定义的相等标准,则可以通过重写isEqual()方法来实现。NSString已经重写了isEqual()方法,NSString的isEqual()方法判断两个字符串相等的标准是:只要两个字符串包含的所有的字符序列相同,则isEqual()返回true,否则返回false。
3、OC中没有像Java和C++那样提供抽象类的语法支持,而在实际项目开发中,总有需要用到抽象类的时候,此时就会选择定义一个父类,并以该父类派生出多个子类,其他程序使用这些类时,实际上返回的是子类的实例,这一系列的类被称为一个类簇(cluster),这个父类就模拟了抽象类的功能。
OC的动态特性允许使用类别(category)为现有的类添加新房,并且不需要创建子类,不需要访问原有类的代码。通过使用类别就可以动态地为现有的类添加新方法,而且可以将类定义模块化地分不到多个文件中。类别同样由接口和实现部分组成,接口和实现部分语法格式如下:
@interface 已有类 (类别名)
//方法定义,类别中只能添加方法,不能添加成员变量
。。。
@end @implementation已有类 (类别名)
//方法实现
。。。
@end
- 类别名的命名很随意,我们自己取定就可以,一般用于描述增加部分的功能
- 通过类别为制定的类添加新方法之后,这个新方法不仅会影响到该类,还会影响到该类的所有子类,每个子类都会获得类别扩展的方法。
- 可根据需要为一个类定义多个类别,不同的类别都可对原有的类增加方法的定义。
- 就编程习惯而言,一般习惯将类别的接口文件命名为“类名+类别名.h”的形式,同样,实现文件则命名位“类名+类别名.m”的形式。
//接口部分
#import <Foundation/Foundation.h> @interface NSArray (Convert) +(NSMutableArray *)arrayFormNumber:(int)number; @end //实现部分
#import "NSArray+Convert.h" @implementation NSArray (Convert) +(NSMutableArray *)arrayFormNumber:(int)number{
NSMutableArray *numberArray=[[NSMutableArray alloc]init];
while (number) {
int last=number%; //取出最后一位;
number=number/;
[numberArray addObject:[NSNumber numberWithInt:last]];
}
return [numberArray autorelease];
} @end - 使用类别可以对类进行模块化设计:在前面类的设计中,类的接口部分在.h文件中定义,类的实现部分在.m文件中定义,且类的实现不能分布到多个.m文件中。但是当某个类特别大时,如果将所有实现都放在一个.m文件中,将会导致这个文件非常大,以至于维护起来非常困难。如果将一个较大的类进行分模块设计,使用类别是一个不错的选择。例如NSWindow类就采用这种设计思想,具体可以在xcode上查看NSWindow.h文件。
- 使用类别来实现私有方法的调用:OC中实际上并没有真正的是有方法,通常而言所说的私有方法指的是没有在接口部分定义而在实现部分定义的方法,这类方法是不允许被调用的,因为没有通过接口部分向外暴露调用接口。在OC中,除了通过NSObject类的performSelector()来执行动态调用从而实现调用私有方法之外,我们还可以通过使用类别来定义前向引用(其实就是通过类别在接口部分补充定义之前未定义的私有方法),从而实现对私有方法的调用。
4、OC中的扩展(extension)和类别相似,扩展相当于匿名类别,不同的是扩展可以定义实例变量。定义扩展的语法格式如下:
@interface 已有类 ()
{
//定义实例变量
}
//方法定义
。。。
@end
- 在语法上,扩展相当于匿名类别。但是在用法上,类别通常是有单独的.h和.m文件,而扩展则用于临时对某一个类的接口进行扩展,类实现部分同时实现类接口部分和扩展中定义的方法。
- 在类的扩展中,可以额外增加实例变量,也可以用@property来合成属性,但是在定义类别是则不允许定义成员变量,也不能用@property合成属性。
#import "vehicle.h"
@interface Vehicle ()
@property(nonatomic, strong) NSString *color;
-(void) drive:(NSString *)name;
@end //在实际使用中,通用的做法是省略掉Vehicle_ext.h文件,而是将其中的内容直接添加在Vehicle.m文件@implementation前部即可
#import "Vehicle_ext.h"
@implementation Vehicle
-(void) drive:(NSString *)name
{
NSLog(@"交通工具名称%@,颜色属性%@",_name,_color);
}
@end
5、协议(protocol)是OC的一个重要知识点,其作用类似于Java中的接口,用于定义多个类应该遵循的规范。协议提提供任何实习那,协议体现的是规范和实现分离的松耦合的设计哲学。
协议定义的是多个类共同的公共行为规范,这些行为是与外部交流的通道,这就意味着协议里通常是定义一组公用方法,但是不会为这些方法提供实现,方法的实现则交给类去完成。协议定义时使用@protocol关键字,在协议中还有两个关键字@optional and @required,@optional 声明的方法可以实现,也可以不实现。@required声明的方法必须实现。具体语法格式如下:
// 定义的协议名称 遵守协议名称
@protocol MyProtocol <NSObject> @required
//定义必选方法 @optional
//定义可选方法 @end //使用协议
@interface 类名 :父类 <协议1,协议2 ... >
- 一个协议可以有多个直接父协议,但协议只能继承协议,不能继承类
- 学一种定义的方法只有方法签名,没有实现。协议中的方法既可以是类方法,也可以是实例方法。
//
// Women.h
// 正式协议的定义
//
// Created by Goddog on 15/1/11.
// Copyright (c) 2015年 Goddog. All rights reserved.
// #import <Foundation/Foundation.h> @protocol Women <NSObject>
//定义协议的方法
@optional //可以不实现该接口的方法
-(void) pretty;
@required //必须实现该接口的方法
-(void) beautiful:(NSString*) count;
@end正式协议的定义Women.h
//
// Man.h
// 正式协议的定义
//
// Created by Goddog on 15/1/11.
// Copyright (c) 2015年 Goddog. All rights reserved.
// #import <Foundation/Foundation.h> @protocol Man <NSObject>
//定义协议的方法
-(void) handsome;
@end正式协议的定义 Man.h
//
// Person.h
// 正式协议的定义
//
// Created by Goddog on 15/1/11.
// Copyright (c) 2015年 Goddog. All rights reserved.
// #import <Foundation/Foundation.h>
#import "Women.h"
#import "Man.h" //协议继承了Women、Man协议
@protocol Person <Women,Man>
//定义协议的方法
-(NSString*) play;
@end
正式协议的定义Person.h
//
// SuperMan.h
// 正式协议的定义
//
// Created by Goddog on 15/1/11.
// Copyright (c) 2015年 Goddog. All rights reserved.
// #import <Foundation/Foundation.h>
#import "Person.h" @interface SuperMan : NSObject<Person> //实现Person的协议 @end
协议的使用SuperMan.h
//
// SuperMan.m
// 正式协议的定义
//
// Created by Goddog on 15/1/11.
// Copyright (c) 2015年 Goddog. All rights reserved.
// #import "SuperMan.h"
#define MAX_CACHE_LINE 10 @implementation SuperMan
{
NSString* playData[MAX_CACHE_LINE]; //使用数组记录所有需要缓存的数据
int dataNum; //记录当前的数量
} //实现协议方法
-(void) pretty
{
//只要还有漂亮的,继续上
while (dataNum > ) {
NSLog(@"正在和%@玩%@",playData[],[self play]);
//剩下的人数减少
dataNum --;
//把列队整体向前移
for (int i = ; i < dataNum; i++) {
playData[i] = playData[i + ];
}
}
} //实现协议方法
-(void) beautiful:(NSString *)count
{
if (dataNum >= MAX_CACHE_LINE) {
NSLog(@"人数已满,不要在上了!");
}
else
{
//把人数添加到列队中
playData[dataNum++] = count;
}
} //实现协议方法
-(void) handsome
{
NSLog(@"英俊");
} //实现协议方法
-(NSString*) play
{ return @"游戏";
} @end
类的实现SuperMan.m
#import <Foundation/Foundation.h>
#import "SuperMan.h" int main(int argc, const char * argv[]) {
@autoreleasepool {
//创建超人对象
SuperMan* superMan = [[SuperMan alloc] init];
//调用协议的方法
[superMan beautiful:@"乌克兰美女"];
[superMan beautiful:@"白俄罗斯美女"];
[superMan pretty];
[superMan handsome]; //创建超人对象,当成Man使用
NSObject<Man>* man = [[SuperMan alloc] init];
//调用Man协议中定义的方法
[man handsome]; //创建超人对象,当成Women使用
id<Women> women = [[SuperMan alloc] init];
//调用Women协议中定义的方法
[women beautiful:@"俄罗斯美女"];
[women pretty];
//[women handsome];//这样是不能调用的
}
return ;
}
类的调用main.m
OC学习7——类别、扩展和协议的更多相关文章
- swift学习笔记4——扩展、协议
之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...
- OC学习笔记——类别(Category)
类别,有些程序员又称之为分类. 类别是一种为现有的类添加新方法的方式,尤其是为系统的做扩展的时候,不用继承系统类,可以直接为类添加新的方法.也可以覆盖系统类的方法. 如: @interface NSO ...
- Snail—OC学习之类别Category
类别就是向类加入一些实用的功能或者方法 利于开发 类能够是系统类.能够是自己定义类 类别跟子类是不一样的.类别仅仅能加入一些方法 属性变量什么的不能够加入 不创建新类,就可以对已有类进行扩展 做项目的 ...
- 【IOS 开发】Objective - C 面向对象高级特性 - 包装类 | 类处理 | 类别 | 扩展 | 协议 | 委托 | 异常处理 | 反射
一. Objective-C 对象简单处理 1. 包装类 (1) 包装类简介 NSValue 和 NSNumber : -- 通用包装类 NSValue : NSValue 包装单个 short, i ...
- OC学习9——反射机制
1.OC提供了3种编程方式与运行环境进行交互: 直接通过OC的源代码:这是最常见的方式,开发人员只是编写OC源代码,而运行环境负责在后台工作. 通过NSObject类中定义的方法进行动态编程:因为绝大 ...
- IOS中类的扩展(协议,分类)
IOS中类的扩展(协议,分类) 扩展类,我们可以使用协议和分类这两种方法,下面我们来分别实现这两种方法: 参考网址:http://www.cnblogs.com/wendingding/p/37095 ...
- IOS开发-OC学习-常用功能代码片段整理
IOS开发-OC学习-常用功能代码片段整理 IOS开发中会频繁用到一些代码段,用来实现一些固定的功能.比如在文本框中输入完后要让键盘收回,这个需要用一个简单的让文本框失去第一响应者的身份来完成.或者是 ...
- OC学习16——对象归档
转载自 OC学习篇之---归档和解挡 OC中的归档就是将对象写入到一个文件中,Java中的ObjectInputStream和ObjectOutputStream来进行操作的.当然在操作的这些对象都 ...
- OC学习6——面相对象的三大特性
我们在学习Java的时候都知道,类有三大特性:继承,封装,多态,这也是面向对象的三大特征.OC学习篇之---类的三大特性(封装,继承,多态) 1.封装(Encapsulation)是指将对象的状态信息 ...
随机推荐
- react入门到进阶(二)
一.react属性与事件 1.State属性 State,翻译过来是状态的意思,所以它就代表着组件的状态.React把用户界面(UI)当做是状态机,想象它有不同的状态然后渲染这些状态,可以轻松让用户界 ...
- thinkphp5源码解析(1)数据库
前言 tp5的数据库操作全部通过Db类完成,比较符合国人的习惯,比如简单的Db::query().Db::execute(),还有复杂的链式操作Db::where('id=1')->select ...
- nyoj 2 括号配对问题 栈
nyoj 2 括号配对问题 题目链接: http://acm.nyist.net/JudgeOnline/problem.php?pid=2 思路: 栈:'(' '['入栈,遇到 ']' ')'出栈 ...
- 项目实战8—tomcat企业级Web应用服务器配置与会话保持
tomcat企业级Web应用服务器配置与实战 环境背景:公司业务经过长期发展,有了很大突破,已经实现盈利,现公司要求加强技术架构应用功能和安全性以及开始向企业应用.移动APP等领域延伸,此时原来开发w ...
- Web前端学习——HTML
HTML其实还是蛮容易学习的,无非就是一些标签.格式的填写,大学的时候也做过网站设计,所以这里主要记录一些常用的HTML标签.属性以及书写方法等. 一.常见HTML格式 主要包含文件type,html ...
- 参加完Rocket MQ Meetup深圳站,回顾和想法
最近一段时间才开始关注云栖社区的公众号,在两周前看到要在深圳科兴科学园办一场Rocket MQ的Meetup.因为从来没有参加过这种线下活动,而且对Rocket MQ比较感兴趣,所以就立即报名参加. ...
- Okio 之初探黄龙
Okio 是一个包装了 java.io 和 java.nio api 的库,以便可以更容易的访问.存储以及处理数据. ByteStrings 和 Buffers Okio 是围绕着两个容器类构建起来的 ...
- Python字符串和日期相互转换的方法
import time,datetime # 日期转换成字符串 print time.strftime("%Y-%m-%d %X", time.localtime()) #字符串转 ...
- Linux安装Nginx以及简单理解
1.Nginx简单介绍 ①.Nginx:一个高性能的HTTP和反向代理服务器,高并发处理很不错. ②.反向代理:在计算机世界里,由于单个服务器的处理客户端(用户)请求能力有一个极限,当用户的接入请求蜂 ...
- 体验CSDN-Markdown
文件夹 文件夹 文本格式化练习 一号标题 1一号标题 二号标题 1 11 2 列表的应用 链接 图片 脚注 表格 序列图 流程图 文本格式化练习: 斜体 斜体的文字 使用鼠标,变成斜体文字 使用键盘C ...