———————————————————————————————————————————
 类别(Category)的声明和实现

实质:类别又叫类目,它其实是对类的一个拓展!但是他不同于继承后的拓展!

(1)在.h文件中,声明类别:

@interface ClassName (CategoryName)   //注意:这里没有冒号,在类名后面直接紧跟小括号,小括号里面是你创建的类别名称
    NewMethod;  //在类别中添加方法
  //★另外不允许在类别中添加变量
@end

说明:

声明类别的格式
①新添加的方法必须写在 @interface 和 @end 之间
②ClassName   现有类的类名(要为哪个类扩展方法)
③CategoryName   待声明的类别名称(也就是你创建的类别名称)
④NewMethod   新添加的方法

(2)在.m文件中,实现类别:

@implementation ClassName (CategoryName)
NewMethod
{
    ……
}
@end

说明:

实现类别的格式
①新方法的实现必须写在 @implementation 和 @end 之间
②ClassName   现有类的类名(要为哪个类扩展方法)
③CategoryName   待声明的类别名称(也就是你创建的类别名称)
④NewMethod   新添加的方法

代码:

代码比较简单,在这里我就不敲了。共有一个Cat类和一个Cat类的拓展类别。总共四个文件。

其中Cat类只是单纯创建了一个类,里面没有做任何的声明和实现。而Cat的拓展类别是通过自动创建出来的,具体拓展类别的操作下面以图片形式呈现:

创建类别时,选择New File,然后选择Objective-C File。

我们会看到多出来了这两个文件。 Cat+doDate.h 和 Cat+doDate.m  ,这也是类别文件的标准书写格式。

这样一个类别就创建成功了。

———————————————————————————————————————————
类别(Category)的使用注意事项

(1)分类只能增加方法,不能增加成员变量、@property(增加@property可能编译不报错,但是运行会出现问题)。
★我们要明白类别是为某个类增加功能(方法),而不是成员变量。

(2)分类可以访问原来类中的成员变量

(3)如果拓展类别中和原类中出现同名的方法,那么优先调用拓展类别中的方法

(4)如果有多个类别中出现同名的方法,那么按照最后编译的那个类别优先调用。

(那么怎么算最后编译的类别呢?我们看下图)

———————————————————————————————————————————
类别(Category)——非正式协议

★要注意,“非正式协议”和我们平时说的协议一点边儿关系都没有。非正式协议是类别(分类)的一种!!!
★非正式协议就是给NSObject类创建的类别(分类),非正式协议一般不需要进行实现,一般在子类中进行方法的重写!
(另外注意一点:非正式协议是NSObject类(还包括他的子类)的类别)

非正式协议优点就是如果你想让某个对象创建出来就有一个方法,那么就可以利用非正式协议写一个。但是这也是他的缺点,如果你不想让其中一个对象有这个方法 ,那么就不能写非正式协议了。所以说,非正式协议的优缺点十分明显,“要么都有,要么都没有”。

非正式协议的应用——利用NSString非正式协议去统计阿拉伯数字的个数:

代码:

//因为我们是统计字符串中阿拉伯数字的个数,所以我们应该为NSString类型增加类别,让每一个字符串都能在创建完成后得到统计其阿拉伯数字个数的方法。
#import <Foundation/Foundation.h>

@interface NSString (numberCountWithNSString)
//我们先写一个类方法去统计字符串中阿拉伯数字的个数
+(int)countWithString:(NSString *)str;

//对象方法去完成上述操作
-(int)countString;
@end

@implementation NSString (numberCountWithNSString)

//我们先写一个类方法去统计字符串中阿拉伯数字的个数
+(int)countWithString:(NSString *)str
{
    unsigned long len=str.length;//整型有无符号(unsigned)和有符号(signed)
    int count=0;//记录阿拉伯数字个数的标记
    for(int i=0;i<len;i++)
    {
        //用一个无符号字符型的变量c去接收传进来的字符串str的每一个字符
        unsigned char c=[str characterAtIndex:i];//characterAtIndex:X 这个方法就是取字符串的第X位字符,将X写为i,然后再套上for循环,自然就是取字符串的每一位的字符了
        if (c<='9'&&c>='0') {
            count++;//符合要求,count+1
        }
    }
    return count;
}

//我们再写一个对象方法去完成上述操作
//不同点在于我们可以直接用字符串去调用该方法,然后用self去调用length和characterAtIndex方法
//-(int)countString;
//{
//    unsigned long len=self.length;//整型有无符号(unsigned)和有符号(signed)
//    int count=0;//记录阿拉伯数字个数的标记
//    for(int i=0;i<len;i++)
//    {
//        //用一个无符号字符型的变量c去接收传进来的字符串str的每一个字符
//        unsigned char c=[self characterAtIndex:i];//characterAtIndex:X 这个方法就是取字符串的第X位字符,将X写为i,然后再套上for循环,自然就是取字符串的每一位的字符了
//        if (c<='9'&&c>='0') {
//            count++;//符合要求,count+1
//        }
//    }
//    return count;
//}

//当然,我们还可以将上面的对象方法简化:直接用对象方法去调用我们写好的类方法,看起来又简便了
-(int)countString;
{
    return [NSString countWithString:self];;
}

@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        int n=[NSString countWithString:@"12321dfs321fsdf"];
        NSLog(@"n=%d",n);
        
        int n2=[@"s2123ads123asdsf" countString];
        NSLog(@"n2=%d",n2);
    }
    return 0;
}

———————————————————————————————————————————
类别(Category)——类的延展(匿名类别)

延展类别又称为扩展(Extension),Extension是Category的一个特例,其名字为匿名(为空),并且新添加的方法一定要予以实现。(一般的Category没有这个限制)

如:@interface Student ()
       @end

上面就是写的 Student 的一个延展。

注意:

①类的延展是绝对私有的,

②类的延展可以不通过创建文件来创建延展,可以直接在类本身的.m文件里写延展的@interface
和@implementation。

③注意类的延展的声明和实现(类的延展的@interface和@implementation)都要写在本类的.m文件里,因为如果把延展的@interface写在.h文件里,那么里面的方法都是public的。

④我们也可以直接省略延展的声明@interface,而直接在本类的.m文件里写延展的实现即可。这里要注意,延展的实现(也就是延展的@implementation)要写在原类的@implementation里面,也就是不能在一个.m文件里写两个@implementation。

代码理解:

*************************************************Dog.h文件**************************************************

#import <Foundation/Foundation.h>

@interface Dog : NSObject
-(void)run;
+(void)bark;
@end

*************************************************Dog.h文件**************************************************

*************************************************Dog.m文件**************************************************

#import "Dog.h"

//延展的声明是可以不写的,我们可以直接在Dog类的@implementation中写延展的实现
//@interface Dog ()
//-(void)eat;
//+(void)eateat;
//@end

@implementation Dog
//原Dog类中我们定义的方法实现
-(void)run
{
    NSLog(@"Dog run!");
    [self eat];
}

+(void)bark
{
    NSLog(@"Dog bark!");
    [self eateat];
}

-(void)love
{
    NSLog(@"ainiaini!");
}

//Dog类的延展中我们声明的方法实现
-(void)eat
{
    NSLog(@"Dog eat!");
    [self lalala];
}

+(void)eateat
{
    NSLog(@"eateat!");
}

-(void)lalala
{
    NSLog(@"lalala!");
}
@end

*************************************************Dog.m文件**************************************************

*************************************************main.m文件**************************************************

#import <Foundation/Foundation.h>
#import "Dog.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Dog *dog=[[Dog alloc]init];
        [dog run];
        [Dog bark];
        
//        [dog eateat];  这样的调用是错误的,延展中定义的方法是绝对私有的,不可以在外面调用,只能通过在.m中我们写的方法实现中用self调用(不管是在 原方法实现中用self调用 还是 在延展的方法实现中用self调用 都可以)
//        延展中定义的方法是绝对私有的,但是他和一类方法不同,就是和在原类中只有实现没有声明的方法不同。后者可以称之为相对私有的方法,而前者是绝对私有的。
    }
    return 0;
}

*************************************************main.m文件**************************************************

———————————————————————————————————————————

Objective-C 【Category-非正式协议-延展】相关推荐

  1. 类别(Category)的作用(三)---添加非正式协议

    在上一篇文章 类别(Category)的作用(二)中,详细说明类别的第二个作用,接下来是类别的第三个作用. 类别作用三:向对象添加非正式协议. 一.概念 显然这个名词是相对于正式协议而言的.什么是正式 ...

  2. Object-C非正式协议与正式协议的区别

    Object-C非正式协议与正式协议的区别 Object-C非正式协议与正式协议的区别 - braddoris的专栏 - 博客频道 - CSDN.NET http://blog.csdn.net/br ...

  3. 非正式协议和正式协议的区别

    这两个概念困扰我很久了,一直都很像搞清楚到非正式协议和正式协议有什么区别和联系,下面结合网上的资料和自己的看法谈谈这个问题. 一.非正式协议 显然这个名词是相对于正式协议而言的.在解释非正式协议之前, ...

  4. OC中的非正式协议与正式协议的区别

    声明:以下内容转自:http://blog.csdn.net/wzzvictory/article/details/9295317# 这两个概念困扰我很久了,一直都很像搞清楚到非正式协议和正式协议有什 ...

  5. OC正式协议和非正式协议的区别

    最近看了些关于objective-c的正式协议和非正式协议的内容,发现还是有些混乱,可能是因为还不熟悉OC,对正式协议和非正式协议的使用还不是很熟练,所以想整理一下 非正式协议,是使用类别catego ...

  6. OC的正式协议和非正式协议

    最近看了些关于objective-c的正式协议和非正式协议的内容,发现还是有些混乱,可能是因为还不熟悉OC,对正式协议和非正式协议的使用还不是很熟练,所以想整理一下 非正式协议,是使用类别catego ...

  7. Objective-C非正式协议与正式协议

    为什么80%的码农都做不了架构师?>>>    类别与类扩展的区别: ①类别中只能增加方法: ②是的,你没看错,类扩展不仅可以增加方法,还可以增加实例变量(或者合成属性),只是该实例 ...

  8. 2016 - 2- 2 非正式协议与正式协议

    在重温<OBJC编程基础>这本书时,对于非正式协议的感觉非常陌生,阅读了一篇王中周的博客,结合自己在书中阅读的内容,做一些总结. 一.非正式协议 显然这个名词是相对于正式协议而言的.在解释 ...

  9. OC正式协议和非正式协议

    1.概念 非正式协议,非正式协议是NSObject类(包括它的子类)的类别,其所有的子类都含蓄地接受了这个协议.非正式协议中的方法是否实现都是可选的,因此在调用非正式协议中的方法之前,需要去检查对象类 ...

最新文章

  1. 使用分页插件的后悔药(二)
  2. 点云法向量与点云平面拟合的关系(PCA)
  3. java中数据结构_JAVA中数据结构总结
  4. java保存图书每日的交易记录
  5. Android ListView 获取Item的值和得到每一个Item的view对象以及得到他们所对应的控件值
  6. [渝粤教育] 西南科技大学 运输组织学 在线考试复习资料
  7. 树莓派硬件编程——(一)用RPi.GPIO库输出信号
  8. 为什么我们会有假期一结束,快乐就终止的感觉?
  9. 华硕a豆安装ubuntu14.04系统开启wifi
  10. VScode插件管理(C/C++)
  11. Mac也能玩3A大作?苹果这是要弄游戏本了吗?
  12. 巨蟹座 vs 狮子座
  13. HTTP/HTTPS账号密码获取
  14. 躺平即是正义,另一种幸福生活的方式
  15. 技术前沿---5G技术的实现原理
  16. AACWallet 上线 小白也能一键发币啦
  17. ROS学习——rotors仿真下载与运行
  18. python实现三级菜单_Python3.5实现的三级菜单功能示例
  19. C 修改服务器代码,rpg c 游戏服务器代码大全
  20. BOGNER博格纳正式宣布杨洋为品牌代言人

热门文章

  1. 中央财经的计算机类学什么时候,2019年3月全国计算机等级考试中央财经大学考试点报名通知...
  2. 未来几十年内人类将可在月球定居:生育繁衍下一代
  3. eSDK BYOD水印功能使用说明
  4. 各种说明方法的例句_十种说明方法
  5. 批量本地英语文档翻译软件
  6. vue项目中使用百度地图api完成自定义搜索功能(包含搜索详细地理位置)
  7. android 位于底部的tab,GitHub - DevinFu/BottomTabBar: Android应用中位于底部的tab栏
  8. PMP笔记:质量管理的七个工具
  9. 浙江杭州工程师职称评审论文要求
  10. 记录一些之前学的APPUI设计知识