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