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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章