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

------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] 6
2014-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");
}
@end
int main()
{
    //创建一个Person类的对象
    //第一次使用Person类
    Person *p = [[Person alloc]init];
    Person *p1 = [[Person alloc]init];
    //第一次使用Student类
    Student *s = [[Student alloc]init];
    return 0;
}
程序输出结果:
Person +load
Student +load
Person +initialize
Student+initialize

总结:

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

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

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

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

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




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值