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

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

第一个问题:继承的前提是这个类可以被继承,因为在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. vim 基础学习之global

    global命令可以在指定模式下,匹配行上进行Ex命令 使用格式: :[range]g[lobal]/{pattern}/[cmd] range-是执行范围(如果缺省,是%) global-命令关键字 ...

  2. python-excel操作之xlrd

    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++操作excel文件+++++++++++++++++ ...

  3. 小项目: low版本的 员工信息程序:

    ### 附加两个文件1 user_info 和worker_info flag = False def logon(): #登录函数 global flag usr = input('Username ...

  4. 程序中为什么会使用while(0)

    https://blog.csdn.net/u012062760/article/details/46446207 关于while(0)实际上是用来宏定义的,这样的宏定义可以避免调用的时候出错. 如下 ...

  5. 洛谷——P1314 聪明的质监员

    https://www.luogu.org/problem/show?pid=1314 题目描述 小T 是一名质量监督员,最近负责检验一批矿产的质量.这批矿产共有 n 个矿石,从 1到n 逐一编号,每 ...

  6. ArcGIS “Error HRESULT E_FAIL has been returned from a call to a COM component.” 异常的解决

    错误提示内容: {System.Runtime.InteropServices.COMException (0x80004005): Error HRESULT E_FAIL has been ret ...

  7. IOS经常使用的性能优化策略

    1.用ARC管理内存 2.对于UITableView使用重用机制 3.UIView及其子类设置opaque=true 4.主进程是用来绘制UI的,所以不要堵塞 5.慎用XIB,由于XIB创建UIVie ...

  8. 编程算法 - 水洼的数量 代码(C)

    水洼的数量 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 有一个大小为N*M的园子, 雨后起了积水. 八连通的积水被觉得是连接在一起的. 请求 ...

  9. android.graphics.Paint方法setXfermode (Xfermode x...

    mPaint = new Paint(); mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SCREEN)); 常见的Xfermod ...

  10. Java学习笔记二.2

    5.运算符:变量的意义就在于可以进行运算,运算需要用运算符来表示,分为以下几种 class test { public static void main(String[] args) { //赋值运算 ...