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

 类别(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)——类的延展(匿名类别)



延展类别又称为扩展(Extendsion),Extendsion是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. Objective-C( Category 分类,非正式协议,分类延展)

    分类: 主要是给原来类增加一些方法;不可以增加成员变量 Person (Person+eat) 非正式协议: 非正式协议就是类别,即凡是NSObject或其子类Foundation框架中的类增加的类别 ...

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

    Object-C非正式协议与正式协议的区别 这两个概念困扰我很久了,一直都很像搞清楚到非正式协议和正式协议有什么区别和联系,下面结合网上的资料和自己的看法谈谈这个问题. 一.非正式协议 显然这个名词是 ...

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

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

  4. 从C#到Objective-C,循序渐进学习苹果开发(3)--分类(category)和协议Protocal的理解

    本随笔系列主要介绍从一个Windows平台从事C#开发到Mac平台苹果开发的一系列感想和体验历程,本系列文章是在起步阶段逐步积累的,希望带给大家更好,更真实的转换历程体验.本文继续上一篇随笔<从 ...

  5. objective-C中的"非正式协议"和“正式协议”

    objective-C中的接口与泛型 先承认我是标题党,因为在obj-c的世界中,官方根本没有"接口"与"泛型"这样的说法. 不过在obj-c中有二个与之接近的 ...

  6. OC基础--分类(category) 和 协议(protocol)

    OC 中的category分类文件相当于 C#中的部分类:OC 中的protocol协议文件(本质是头文件)相当于 C#中的接口.今天就简单说明一下OC中的这两个文件. 由于视频中的Xcode版本低, ...

  7. Objective-C中的类目(Category),延展(Extension)

    类目和延展的作用都是为了扩展一个类. Objective-C中的类目(Category) 一.类目的定义和作用 类目也叫分类,英文Category,在没有原类.m文件的基础上,给该类添加方法. 比如, ...

  8. category与协议的不同

    1,category是针对类进行扩展,而且该类必须有里面的所有成员 协议不同可以选择性实现 2,category是针对一个具体的类实现,其他类没有 协议允许任何类使用,只要实现以后只能通过重写修改 3 ...

  9. objective c, category 和 protocol 中添加property

    property的本质是实例变量 + getter 和 setter 方法 category和protocol可以添加方法 category 和 protocol中可以添加@property 关键字 ...

随机推荐

  1. C# 程序员最常犯的 10 个错误

    关于C# C#是达成微软公共语言运行库(CLR)的少数语言中的一种.达成CLR的语言可以受益于其带来的特性,如跨语言集成.异常处理.安全性增强.部件组合的简易模型以及调试和分析服务.作为现代的CLR语 ...

  2. 设备\Device\Harddisk1\DR1 有一个不对的区块

    近期遇到一个windows上的Oracle DB system表空间有问题.然后第一个反应就是查看windows的日志查看器,确实发现了报错: 设备\Device\Harddisk1\DR1 有一个不 ...

  3. 0c-39-ARC下单对象内存管理

    1.ARC工作原理详述 ARC是Objective-C编译器的特性,而不是运行时特性或者垃圾回收机制,ARC所做的只不过是在代码编译时为你自动在合适的位置插入release或autorelease A ...

  4. 给大家普及一下CPU和SOC的基本知识,好让大家在盲目喝彩做出基本的判断

    转载:http://bbs.tianya.cn/post-worldlook-544367-1.shtml 目前,华为推出了自己的四核手机,用自己的SOC,所以很多不明就里的人开始嚷嚷国产处理器的骄傲 ...

  5. 聊聊 Xcode 项目文件中的 project.pbxproj

    project.pbxproj 文件被包含于 Xcode 工程文件 *.xcodeproj 之中,存储着 Xcode 工程的各项配置参数.它本质上是一种旧风格的 Property List 文件,历史 ...

  6. iOS一分钟学会环形进度条

    有几篇博客写到了怎么实现环形进度条,大多是使用Core Graph来实现,实现比较麻烦且效率略低,只是一个小小的进度条而已,我们当然是用最简单而且效率高的方式来实现.先看一下这篇博客,博客地址:htt ...

  7. 重构22-Break Method(重构方法)

    这个重构是一种元重构(meta-refactoring),它只是不停地使用提取方法重构,直到将一个大的方法分解成若干个小的方法.下面的例子有点做作,AcceptPayment方法没有丰富的功能.因此为 ...

  8. mysql 重命名表名

    先创建一张表: -- 创建用户表 CREATE TABLE user10( id SMALLINT UNSIGNED KEY AUTO_INCREMENT, username ) NOT NULL U ...

  9. 正则转nfa:完成

    太累了,感觉不会再爱了.问题已经解决,具体的懒得说了. #include "regular_preprocess.h" //这个版本终于要上nfa了,好兴奋啊 //由于连个节点之间 ...

  10. Kinect For Windows V2开发日志二:Kinect V2的基本参数

    以下内容节选自Heresy的博客:   彩色影像:1920 x 1080 @ 30 / 15 FPS(根据环境亮度) 深度影像:512 x 424 @ 30 FPS.16bit 距离值(mm).可侦测 ...