首先我们来看一下场景,如果我们现在想对一个类进行功能的扩充,我们该怎么做?

对于面向对象编程的话,首先会想到继承,但是继承有两个问题:

第一个问题:继承的前提是这个类可以被继承,因为在Java中有些类是不允许继承的,定义成final类,同样的OC中也是有不可以继承的类

第二个问题:这个类可以被继承,但是继承我们知道是侵入性的,就是我可能只是想实现一个功能,但是继承之后,子类就会把父类的所有功能(属性和方法)都继承了,这个代价太大了。没必要

所以对于Java中,我们可以使用聚合的方式去实现,

而对于C++的话,直接在定义一个功能类,然后让这个目标类继承功能类,因为C++中是可以多继承的

Java和OC是单继承的,不允许多继承

那么在OC中当然我们也可以像Java那种方式去采用聚合处理,但是OC中还有一个更强大的处理方式,那就是类别了,下面来看一下例子:我们现在想给NSString类提供一个校验邮箱的方法validateEmail,OC中NSString类就是不可以继承的。

不说了,直接看代码:

NSString+Extension.h

  1. //
  2. //  Extension.h
  3. //  09_ClassTarget
  4. //
  5. //  Created by jiangwei on 14-10-11.
  6. //  Copyright (c) 2014年 jiangwei. All rights reserved.
  7. //
  8. #import <Foundation/Foundation.h>
  9. //定义类别的文件命名规则:类名+类别名称,如“NSString+Extension.h"
  10. @interface NSString (Extension)
  11. - (BOOL)validateEmail;
  12. //覆盖NSString中的intValue方法
  13. - (NSInteger)intValue;
  14. @end

NSString+Extension.m

  1. //
  2. //  Extension.m
  3. //  09_ClassTarget
  4. //
  5. //  Created by jiangwei on 14-10-11.
  6. //  Copyright (c) 2014年 jiangwei. All rights reserved.
  7. //
  8. #import "NSString+Extension.h"
  9. @implementation NSString (Extension)
  10. - (BOOL)validateEmail{
  11. NSRange range = [self rangeOfString:@"@"];
  12. if(range.location == NSNotFound){
  13. return NO;
  14. }else{
  15. return YES;
  16. }
  17. }
  18. //这里可以看出,这里是没办法调用NSString中得intValue方法,这个和继承有区别的
  19. - (NSInteger)intValue{
  20. NSLog(@"intValue");
  21. return 0;
  22. }
  23. @end

这里我们就定义了一个类目,下面来解释一下:

类别文件的定义格式:

类别的文件名的格式:"需要添加类别的类名+类别的名称"

比如这里我们需要对NSString类添加一个类目Extension,那么文件名就是:NSString+Extension.h和NSString+Extension.m

类目的定义格式:

@interface 需要添加类别的类名 (类别名)

....

@end

这个和类定义格式差不多,就是在后面多了一个括号类别名

例如:

@interface NSString (Extension)

....

@end

类别名是可以随便取的

看到上面的代码,在NSString+Extension.h中

我们就可以定义validateEmail方法了,同时我们在定义了一个intValue方法

intValue方法是NSString本身就有的,这里就是为了演示一下,如果在添加的类目中重新定义了类中的已有的方法,那么类目中的方法会被覆盖,和类的继承差不多,但是这里有一点需要注意,这里是不能使用super关键字去调用NSString的intValue方法的,所以intValue覆盖了NSString类中的intValue方法之后,NSString类中的intValue方法原先的功能就没有了,这个得注意一下。

看一下测试代码

main.m

  1. //
  2. //  main.m
  3. //  09_ClassTarget
  4. //
  5. //  Created by jiangwei on 14-10-11.
  6. //  Copyright (c) 2014年 jiangwei. All rights reserved.
  7. //
  8. #import <Foundation/Foundation.h>
  9. #import "NSString+Extension.h"
  10. //这里只是为了演示如果想扩展一个类的功能,可以通过继承的方式去实现
  11. //但是通过继承来实现这项功能话,有点大材小用的感觉,因为我们只需要一个判断邮箱的合法性的方法,所以继承就大了,没必要
  12. //但是这里会出错,因为NSString是不允许继承的
  13. //所以这里我们就要用到一个很强大的技术:类目
  14. //类目的定义和累的定义相似,在.h文件里声明,.m文件中实现方法
  15. //类目可以覆盖方法,但是不会再执行之前的那个方法了,而是调用新的方法
  16. //类目不能为类添加属性(实例变量)
  17. int main(int argc, const charchar * argv[]) {
  18. @autoreleasepool {
  19. NSString *s = @"123456@qq.com";
  20. BOOL isEmail = [s validateEmail];
  21. if(isEmail){
  22. NSLog(@"有效邮箱");
  23. }else{
  24. NSLog(@"无效邮箱");
  25. }
  26. //调用的是我们类目中的intValue方法
  27. NSInteger i = [s intValue];
  28. NSLog(@"intValue is %i",i);
  29. }
  30. return 0;
  31. }

这样我们就给NSString类添加了一个校验邮箱的方法,同时类目中的intValue方法也会覆盖原先类中的intValue方法。

通过这个例子,我们可以看到OC中的类目真的很强大呀!!

而且类目其实还有一个隐藏的用处,从他的字面意思上就知道具有分类的作用,比如一个类中的方法有时候我们可能会需要进行分类(比如:打印分类,比较分类等),这样代码看上去也很优雅。我们可以翻看Foundation框架中的NSArray类(这个类我们后面会说到的,和Java中的List差不多):

还有一个类目。

这里我们也了解到了,一个类是可以定义多个类目的。而且类目的作用可以沿袭到子类,就是父类的类目中的方法子类依然可以使用super关键字进行调用的。

总结

这一篇文章就介绍了OC中的一个强大功能类目,这个在对以后的扩展性起到至关重要的作用,也算是OC中的一个重点了,后续我们会经常用到这个功能。

OC学习篇之—写类别(类的扩展)的更多相关文章

  1. OC学习篇之---总结和学习目录

    今天终于把OC的基础知识学习完了,但是这些知识只是最基础的,还有很多高级知识,这个可能需要后面慢慢的去学习才能体会到.下面就是这次学习OC的目录教程,如果大家发现有什么不正确的地方,请指正,小弟是新生 ...

  2. OC学习篇之---单例模式

    在之前的一片文章中介绍了对象的拷贝相关知识:http://blog.csdn.net/jiangwei0910410003/article/details/41926531,今天我们来看一下OC中的单 ...

  3. OC学习总结之面向对象和类

    OC学习总结之面向对象和类   Objective-c是c语言的母集合,它的原意就是在原始的c语言的主体上加入面向对象的特性.1.面向对象和面向过程  面向对象和面向过程是编程的两种思考方式.面向对象 ...

  4. Java程序猿的JavaScript学习笔记(10—— jQuery-在“类”层面扩展)

    计划按例如以下顺序完毕这篇笔记: Java程序猿的JavaScript学习笔记(1--理念) Java程序猿的JavaScript学习笔记(2--属性复制和继承) Java程序猿的JavaScript ...

  5. (转载)OC学习篇之---类目的概念和使用

    上一篇文章介绍了OC中的@class关键字的使用,这一篇我们介绍一下,OC中的一个特有的亮点:类目 首先我们来看一下场景,如果我们现在想对一个类进行功能的扩充,我们该怎么做? 对于面向对象编程的话,首 ...

  6. OC学习篇之---类目的概念和使用

    上一篇文章介绍了OC中的@class关键字的使用http://blog.csdn.net/jiangwei0910410003/article/details/41774747,这一篇我们介绍一下,O ...

  7. (转载)OC学习篇之---概述

    前言 终于开启了OC的学习篇了,之前由于工作上的事,学习就一直搁浅了,不过最近由于各种原因,感觉必须要开启iOS的开发旅程了,不然就老了.因为之前一直是做Android的,所以学习iOS来就没那么费劲 ...

  8. (转载)OC学习篇之---类的三大特性:封装,继承,多态

    之前的一片文章介绍了OC中类的初始化方法和点语法的使用,今天来继续学习OC中的类的三大特性,我们在学习Java的时候都知道,类有三大特性:继承,封装,多态,这个也是介绍类的时候,必须提到的话题,那么今 ...

  9. OC学习篇之---类的三大特性(封装,继承,多态)

    之前的一片文章介绍了OC中类的初始化方法和点语法的使用:http://blog.csdn.net/jiangwei0910410003/article/details/41683873,今天来继续学习 ...

随机推荐

  1. 40.Node.js Web 模块

    转自:http://www.runoob.com/nodejs/nodejs-module-system.html 什么是 Web 服务器? Web服务器一般指网站服务器,是指驻留于因特网上某种类型计 ...

  2. PHP 获取完整URL地址

    /** * 获取当前完整URL * @return string */ function get_url() { $sys_protocal = isset($_SERVER['SERVER_PORT ...

  3. JavaScript笔记(5)

    1.return 跳出当前函数 返回一个结果 <script> //return可以跳出当前函数 所以return写在函数的最后一行 function out() { return fun ...

  4. 【Educational Codeforces Round 36 B】Browser

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 分类在区间里面和左边.右边三种情况. 看看l的左边有没有标签.r的右边有没有标签. 就能做完了. [代码] #include < ...

  5. 【MySQL】常见错误与经常使用命令的集锦

    [背景介绍]     在使用SQL Server数据库期间,想必大家一定都有过解决各种问题的经历了.非常多时候,都会在大家的博客中看到问题与解决方式. 如今开发使用的是MySQL数据库.如今来看,发现 ...

  6. code blocks主题颜色配置

    添加配置文件 注意:在添加这些自定义配置文件之前一定要先将之前的文件配置备份! 在添加时一定要确保Code::Blocks**没有**在运行!下载下面的文件,并将其添加到C:\Users\<你的 ...

  7. 洛谷P3273 [SCOI2011]棘手的操作

    题目描述 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i],接下来有如下一些操作:U x y: 加一条边,连接第x个节点和第y个节点A1 x v: 将第x个节点的权 ...

  8. 不用浏览器,直接用代码发送文件给webservices所在服务器 并且可以周期行的发送

    package com.toic.test; import java.io.DataInputStream; import java.io.DataOutputStream; import java. ...

  9. sql server向表里添加字段

    ADD mcTypeE VARCHAR(20) NULL,mcGoodsE VARCHAR(20) NULL, mcTypeF VARCHAR(20) NULL,mcGoodsF VARCHAR(20 ...

  10. CISP/CISA 每日一题 19

    CISSP 每日一题(答)What determines how often an audit should be performed? Risk     What policy requires u ...