Objective-C中的类目,延展,协议

01).分类Categroy

又称扩展类,在不改变原来的类内容的基础上,为类增加一些方法。

01>.分类的使用注意

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

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

(3)分类中可以重新实现原来类中的方法,但是会覆盖掉原来的方法,导致原来的方法无法再使用(警告);

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

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

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

(7) 分类中可以写@property 但只能生成setter getter 的声明,实现得自己写

(8) 本类中的真私有属性,分类是不能访问的,但是可以通过相应的getter setter方法来访问

(9) 分类中可以存在与本类同名的方法,不论是否引入分类,调用的都是分类的方法

(10)与继承不同,不可在扩展方法中通过super调用原始方法.

举例:人类固有方法->吃饭,现在给人增加一个->学习的方法

//定义类HMPerson.h
#import <Foundation/Foundation.h>

@interface HMPerson : NSObject

-(void)eat;

@end

//HMPerson.m
#import "HMPerson.h"

@implementation HMPerson
-(void)eat{

    NSLog(@"人在吃东西");

}
@end

//扩展HMPerson+study.h
#import "HMPerson.h"

@interface HMPerson (study)
- (void)study;
+ (void)study;
@end

//HMPerson+study.m
#import "HMPerson+study.h"

@implementation HMPerson (study)
- (void)study
{
    NSLog(@"人在学习,对象方法");
}
+ (void)study
{
    NSLog(@"人在学习,类方法");
}
@end

//main.m
#import <Foundation/Foundation.h>
#import "HMPerson.h"
#import "HMPerson+study.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {

        HMPerson *p = [[HMPerson alloc] init];

        [p eat];

        [p study];//分类中的对象方法

        [HMPerson study];//分类中的类方法,开发中常用

    }
    return 0;
}

02).非正式协议(informal protocol)与正式协议(formal protocol)

  • 非正式协议(informal protocol):使用类别category来实现,所谓的非正式协议就是类别,即凡是NSObject或其子类的类别,都是非正式协议。
    举例:写一个方法计算当前字符串对象中有多少个阿拉伯数字.
//声明NSString+countFunction.h
#import <Foundation/Foundation.h>

@interface NSString (countFunction)

- (NSUInteger)numberOfCount;

@end

//实现NSString+countFunction.m
#import "NSString+itheima.h"

@implementation NSString (itheima)
//注:不需要参数.因为当前对象就是字符串.
- (NSUInteger)numberOfCount
{
    //计算当前字符串对象中有多少个阿拉伯数字.
    NSUInteger count = 0;
    //遍历当前这个字符串对象.
    for(int i = 0; i < self.length; i++)
    {
        unichar ch =  [self characterAtIndex:i];
        if(ch >= '0' && ch <= '9')
        {
            count++;
        }
    }
    return count;
}
@end

//测试非正式协议main.m
#import <Foundation/Foundation.h>
#import "NSString+itheima.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {

        NSString *str = @"1dihnwdiwhifn23ifnr2ieh3n2ie4n2in4ri3nrt3ibni3nt5";

        NSUInteger count =  [str numberOfCount];
        NSLog(@"count = %lu",count);     
    }
    return 0;
}
  • 正式协议(formal protocol):指的是一个以@protocol方式命名的方法列表,与非正式协议相比不同的是,它要求显示的采用协议。
    //协议–begain
//protocol协议 HMProtocol.h
#import <Foundation/Foundation.h>

@protocol HMProtocol <NSObject>

- (void)work;
//定义必须实现的方法@required
@required
-(void)requiredFunction;

//定义可选的方法@optional
@optional
-(void)optionalFunction;

@end

//人类声明HMPerson.h
#import <Foundation/Foundation.h>
#import "HMProtocol.h"//这里需要把协议的头文件引进来

@interface HMPerson : NSObject<HMProtocol>//这里必须遵守协议

- (void)eat;

@end

//人类实现HMPerson.m
#import "HMPerson.h"

@implementation HMPerson
- (void)eat
{
    NSLog(@"人在吃");
}

- (void)work//实现协议里面的方法
{
    NSLog(@"人在工作");
}

//实现协议中必须的方法:required方法
-(void) requiredFunction
{
    NSLog(@"RequiredFunction PS: 我是协议中required方法,不实现我会有警告!");
}

//实现协议中可选的方法,不实现不会有警告
-(void) optionalFunction
{
    NSLog(@"OptionalFunction PS: 我是protocol中得可选协议,不实现我,不会有警告!");
}

@end

03).延展Extension

是1个特殊的分类
匿名;只有声明,没有实现;和本类共享1个实现

01>.语法

@interface 本类名 ()
@end

延展的第一种形式(独立出来,不常用)
举例:人已有打招呼方法,请延展跑步方法

//声明类HMPerson.h
#import <Foundation/Foundation.h>

@interface HMPerson : NSObject

@property(nonatomic,strong)NSString *name;
@property(nonatomic,assign)int age;

- (void)sayHi;

@end

//扩展HMPerson_newFunction.h  有独立头文件
#import "HMPerson.h"

@interface HMPerson ()

@property(nonatomic,assign)int num2;

- (void)run;

@end

//实现HMPerson.m
#import "HMPerson.h"
#import "HMPerson_newFunction.h"

@implementation HMPerson

- (void)run
{
    NSLog(@"piapia的跑");
}

- (void)sayHi
{
    NSLog(@"大家好,我来了!");
}

@end

//main.m
#import <Foundation/Foundation.h>
#import "HMPerson.h"
#import "HMPerson_newFunction.h"//需要把延展的头文件引入进来

int main() {
    @autoreleasepool {

        HMPerson *p = [[HMPerson alloc] init];

        [p run];//调用延展里面的方法

        p.num2 = 20;//访问延展里面的属性        
    }
    return 0;
}

延展的第二种形式(写在.m文件中,开发常用)

//声明类HMPerson.h
#import <Foundation/Foundation.h>

@interface HMPerson : NSObject

@property(nonatomic,strong)NSString *name;
@property(nonatomic,assign)int age;

- (void)sayHi;

@end

#import "HMPerson.h"


//实现HMPerson.m
//这是延展(不单独出去,直接写在.m文件里面)
@interface HMPerson ()

@property(nonatomic,assign)int num2;

- (void)run;

@end

@implementation HMPerson

- (void)run
{
    NSLog(@"piapia的跑");
}


- (void)sayHi
{
    NSLog(@"大家好,我来了!");

    [self run];//放在.m文件的延展是私有的,只能在当前类中使用

    self.num2 = 20;//放在.m文件的延展是私有的,只能在当前类中访问
}

@end

//main.m
#import <Foundation/Foundation.h>
#import "HMPerson.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {

        HMPerson *p = [[HMPerson alloc] init];

        [p run];//这里调用会出错,因为放在.m文件的延展是私有的

        p.num2 = 20;//这里访问会出错,因为放在.m文件的延展是私有的

    }
    return 0;
}
02>.使用注意

a.分类中只能新增方法,可以写@property 但是只会生成getter
b.延展中可以写属性
也可以写@property,会自动的生成私有属性

03>.作用

a.只能在内部访问,不能再外面访问
b.私有化类的成员

04>.注意

a.属性需要被私有化

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值