黑马程序员——OC基础——分类和类的本质

来源:互联网 发布:大疆 人工智能 编辑:程序博客网 时间:2024/04/28 01:16

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

一,分类

定义:分类是OC特有的语言,分类是对类的扩展,是在不改变原来类的代码的情况下,为类增加更多方法和功能的一种方法。

实质:分类本质上是类的一部分

语法:文件里语法为:@interface 主类类名 (分类类名)

通常文件的命名规则为:主类名 + 分类名称

调用方法:只需要向主类引用发送消息即可

使用xcode添加一个分类:选择file ->new ->objictive-c category 

在类中添加一个方法:

#import "Person.h"@interface Person (YY)- (void)study;@end
Study方法的实现:
#import "Person+YY.h"@implementation Person (YY)- (void)study{    NSLog(@"调用了分类的study方法");}@end
测试程序:
#import <Foundation/Foundation.h>#import "Person.h"#import "Person+YY.h"int main(){    Person *p = [[Person alloc]init];    //调用了分类的方法    [p study];    return 0;}
输出结果:
调用了分类的study方法
分类不但可以给自定义的类添加功能,还可以给不知道源代码的类添加功能

分类的使用注意:

1,分类只能增加方法(包括类方法和对象方法),不能增加成员变量

2,在分类方法的实现中可以访问原来类中的成员变量

3,分类可以重写实现原来类中的方法,但是会覆盖掉原来的方法,导致原来的方法无法再使用

4,方法调用的优先级:分类 ->原来的类 ->父类,若包含有多个分类,则最后参与编译的分类优先;

5,在很多情况下是给系统自带的类添加分类,如NSObject和NSString,因为有的时候系统类可能满足不了我们的需求

6,在大规模的应用中,通常是把相应的功能写在同一个分类,可以有无线个分类,对原有类进行扩充,一般分模块写,一个模块一个分类。

7,通常,分类的定义在.h文件中,但是也可以定义在.m文件里,此时分类的方法就变成私有方法

分类变成联系:

1,给NSString添加一个类方法,计算某个字符串对象中阿拉伯数字的个数

2,给NSString添加一个对象方法,计算当前字符串对象中阿拉伯数字的个数。

分类中方法的声明:

#import <Foundation/Foundation.h>@interface NSString (NumberOfs)//为NSString定义一个类放方法,计算某个字符串中阿拉伯数字的个数+ (int)NumberOfString:(NSString *)str;//为NSString添加一个对象方法,计算当前对象中阿拉伯数字的个数- (int)NumberCount;@end
分类方法的实现:
#import "NSString+NumberOfs.h"@implementation NSString (NumberOfs)+ (int)NumberOfString:(NSString *)str{    int count = 0;    for(int = 0;int < str.length;i++)    {         //去除字符串第i个位置的字符给c         unichar c  = [str characterAtIndex: i];         if(c > '0' && c < '9')                 count++;     }     return count;}//实现对象方法- (int)NumberCount{     int count = 0;    for(int = 0;int < str.length;i++)    {         //去除字符串第i个位置的字符给c         unichar c  = [str characterAtIndex: i];         if(c > '0' && c < '9')                 count++;     }     return count;}@end
程序测试:
#import <Foundation/Foundation.h>#import "NSString+NumberOfs.h"int main(){    //调用分类中实现的类方法    int a = [NSString NumberOfString:@"123xxc234k"    NSLog(@"%d",a);        //调用分类中实现的对象方法    int b = [@"dhfii234kk" NumberCount];    NSLog(@"%d",b);    return 0;}
程序输出结果:
2014-12-13 14:15:39.078 分类练习[1374:303] 62014-12-13 14:15:39.078 分类练习[1374:303] 3

二,类的本质

类的本质也是一个对象,是class类型的对象,简称”类对象“。

class类型的定义

typedef struct class *class;
类名就代表着类对象,每个类只有一个类对象

利用class创建Person类

利用Person创建Person 类型的对象

Person *p = [[Person alloc]init];
获取内存中类对象有两种方法:

1,指向类的对象的指针调用class方法

Class c = [p class];
2,使用类名调用class方法:
Class d = [Person class];
注意:c和d打印出来的地址相同,class c2 = [p class];可以证明所有的类对象公用一个类方法


类的加载和初始化

Person类的声明和实现

@interface Person :NSObject@end@implementation Person//重写类的加载和初始化方法+ (void)load{     NSLog(@"Person +load")}+ (void)initialize{    NSLog(@"Person+initialize");}@end
程序测试:

Student类的声明和实现,Student类继承自Person

@interface Student :Person@end@implementation Student//重写类的加载和初始化+ (void)load{    NSLog(@"Student +load");}+ (void)initialize{    NSLog(@"Student+initialize");}@endint main(){    //创建一个Person类的对象    //第一次使用Person类    Person *p = [[Person alloc]init];    Person *p1 = [[Person alloc]init];    //第一次使用Student类    Student *s = [[Student alloc]init];    return 0;}
程序输出结果:
Person +loadStudent +loadPerson +initializeStudent+initialize

总结:

1,当程序启动时,就会加载项目中所有的类和分类,而且加载后会调用每个类和分类的+load方法,只会调用一次

2,当第一次使用某个类时,就会调用当前类的+initialize方法

3,先加载父类,再加载子类(先调用父类的+load方法,在调用子类的+load方法,最后调用分类的+load方法),先初始化父类再初始化子类

4,重写+initialize方法可以监听类的使用情况

注意:初始化的时候,如果在分类中重写了+initialize方法,则会覆盖掉父类的




0 0