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

来源:互联网 发布:南风知我意2百度云 编辑:程序博客网 时间:2024/05/16 10:59

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.属性需要被私有化

原创粉丝点击