iOS中協議和延展的區別

延展部分

一、延展的介紹

延展也叫Extension,形式和類目相同,是一種特殊形式的類目(匿名類目),主要是爲現有類添加私有方法,可以通過建立文件創建延展,也可以直接在現有類的.m中聲明延展。

延展的聲明形式:

@interface 現有類名 ()

//這裏可以聲明方法

@end

二、延展的特點(注意事項)

1、如果括號裏沒有類目名,則認爲延展裏面的方法爲全都必須實現,如果有名,則認爲是可選實現。
2、雖然延展是給一個類定義私有方法,但是OC裏面沒有絕對的私有方法(可以被外部和子類強制調用的,當然也可以被子類繼承,只是子類沒有調用接口所以要強制調用),另外延展裏面聲明的變量只能在該類內部使用,外界訪問不了。
3、如果是通過創建文件建立的延展,.h文件不能加實例變量,只能添加方法。

三、舉一個延展的例子

建立延展有兩種方式,第一種,直接在現有類的.m中聲明一個延展(其實這種方法可以省略聲明,沒有在現有類.h中聲明的現有類方法都相當於是延展方法),比較簡單,不再做詳細的介紹;第二種是通過創建文件來建立延展,建立流程

new file->Source->Objective-C File->next
File Type 可以選取類目延展或者協議 File處填寫延展名字,我們這裏就填寫一個“Extension”

下面通過代碼舉一個例子來看看

首先建一個項目,主頁面MainViewController,建立一個現有類MyClass併爲現有類建立一個延展(通過建立文件,只有一個.h文件)MyClass_Extension,下面來看具體代碼:

在MyClass_Extension.h中

//這裏是MyClass.h
#import "MyClass.h"
@interface MyClass ()
//這裏可以聲明方法,但是不可以聲明成員變量
-(void)method1;
@end

MyClass.h中

#import <Foundation/Foundation.h>
@interface MyClass : NSObject
//這裏聲明的方法和成員變量可以被外界調用也可以被子類繼承
-(void)method;
@end

MyClass.m中

#import "MyClass.h"
@interface MyClass ()//延展
{
    int a;
}//這裏聲明的成員變量和方法爲私有,但是方法可以被外界和子類強制調用,也可以被子類繼承
-(void)method2;
@end

@implementation MyClass
-(void)method
{
    NSLog(@"method");
}
//在這裏對延展方法1進行實現
-(void)method1
{
    NSLog(@"method1");
}
//有聲明的完全私有方法,可以強制調用,但是會警告
-(void)method2
{
    NSLog(@"method2");
}
//沒有聲明,與上面一樣,可以強制調用,但是會有警告
-(void)method3
{
    NSLog(@"method3");
}
@end

在MainViewController是這樣調用的

#import <Foundation/Foundation.h>
#import "MyClass.h"
#import "MyClass_Extension.h"//導入文件延展(調用延展方法聲明)

        MyClass *m=[[MyClass alloc]init];
        [m method];
        [m method1];//調用延展方法(只要導入頭文件)
        //下面兩個方法爲私有,但是也可以這樣強制調用,在子類中也可以
        [m method2];
        [m method3];

總而言之,現在延展用處並不大了,也許後面再用到延展的時候是很少的了,所以只是簡單介紹一下。



協議部分

一、協議的介紹

協議的聲明結構

@protocol MyProtocol <NSObject>//可以繼承其它的協議
//這裏寫方法聲明
@end

協議不是類,只是一個其他對象可以實現的接口,聲明瞭可以被其他的類實現的方法。

二、協議的作用與特點

1.在OC中是沒有多繼承的概念的,我們可以用協議來實現類似多繼承的模式(實現類之間的通訊);

2.和其他高級語言中接口不同的是協議中定義的方法不一定是必須實現的,我們可以通過關鍵字進行@required和@optional進行設置,如果不設置則默認是@required(注意ObjC是弱語法,即使不實現必選方法編譯運行也不會報錯);

3.協議的實現只能在類的聲明上,不能放到類的實現上(也就是說必須寫成@interface Person:NSObject<AnimalDelegate>而不能寫成@implementation Person<AnimalDelegate>);

4.協議中不能定義屬性、成員變量等,只能定義方法;

5.協議只負責聲明方法,方法的實現是在遵循協議的類中代爲實現的;

6.在想要調用協議方法的類裏面聲明一個id類型的遵循協議的屬性或者成員變量,想辦法讓這個屬性或者成員變量的值=某一個遵循協議並實現了協議方法的類所實例化的對象,之後就可以通過這個屬性活成員變量來調用協議裏面的方法;

7.一個協議可以被多個類遵循實現,當然一個類也可以遵循實現多個協議裏的方法;

8.協議可以自己新建一個文件,也可以直接聲明在想要調用協議方法的類的.h文件中。

三、一個協議使用的例子

首先,我們建一個項目,一個主頁MainViewController,一個遵循協議實現協議方法的類MyClass,一個聲明屬性調用協議方法的類diaoYong,以及一個協議文件MyProtocol,(協議文件建立方法new file->Source->Objective-C File->next  =>File Type 可以選取類目延展或者協議 File處填寫協議名字,我們這裏就填寫一個“MyProtocol”

接下來看代碼:MyProtocol.h中

#import <Foundation/Foundation.h>
@protocol MyProtocol <NSObject>
-(int )addx:(int)x andy:(int)y;//默認爲必須實現方法
//@optional//關鍵字爲可選實現方法
//-(void)method1;
//@required//關鍵字必須實現方法
//-(void)method2;
@end

實現協議的類MyClass.h

#import <Foundation/Foundation.h>
#import "MyProtocol.h"//導入頭文件
//尖括號內是對協議的遵循
@interface MyClass : NSObject<MyProtocol>
@end
MyClass.m中

#import "MyClass.h"
@implementation MyClass
//實現協議中的方法
-(int )addx:(int)x andy:(int)y
{
    return x+y;
}
@end

通過屬性調用協議方法的類diaoYong.h

#import <Foundation/Foundation.h>
#import "MyProtocol.h"
@interface diaoYong : NSObject
//遵循協議的屬性,用來調用協議的方法
@property (strong,nonatomic) id<MyProtocol> delegate;
-(void)methodAddX:(int)x andY:(int)y;//自己的方法
@end
diaoYong.m中

#import "diaoYong.h"
@implementation diaoYong
-(void)methodAddX:(int)x andY:(int)y
{
    //用遵循協議的屬性調用協議方法
    NSLog(@"%d",[self.delegate addx:x andy:y]);
}
@end

最後在主頁中調用的代碼

#import <Foundation/Foundation.h>
#import "diaoYong.h"
#import "MyClass.h"

        diaoYong *dy=[diaoYong new];
        MyClass *mc=[MyClass new];
        dy.delegate=mc;//將遵循協議的屬性與實現協議的類對象關聯起來,很重要
        [dy methodAddX:10 andY:10];

輸出結果:[1663:89363] 20 至此一個協議的最基本的用法介紹完成


備註:其實協議最重要的一個用途就是實現iOS中常用的一種代理(委託)設計模式
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章