有沒有辦法將3G的功能抽離出來啊,若下次我希望iPad mini也支援此功能,我只要把這個功能加上去不就ok了,有辦法作到嗎? |
我是protocol, 沒問題,我幫你訂定什麼是3G上網應有的功能。 |
我是類別class, 除了可以使用我來定義什麼是iPad, iPhone, iPad mini外, 我還可以跟協定protocol合作, 只要跟我說我要支援哪些協定protocol, 你就會擁有此協定的功能了。 |
1. 建立Internet3G協定
- 新增檔案,並選Objective-C protocol類型的檔案
- 輸入協定名稱為Internet3G
2. 定義Internet3G協定的屬性與方法
- 於Internet3G.h加入is3GConnected屬性,表示是否已連結3G網路
- 加入connectInternetWith3G方法,以透過此方法連上3G網路
Internet3G.h
#import <Foundation/Foundation.h>
//使用@protocol定義Internet3G協定,
//<NSObject>是建立此protocol時自動帶入的,
//基本上是可移除。
@protocol Internet3G <NSObject>
//協定中,有個是否3G已連結的屬性
@property bool is3GConnected;
//協定中,定義透過3G連結的方法
-(void) connectInternetWith3G;
@end
3. 建立iPad、iPadmini、iPhone類別,實作Internet3G協定
- 分別建立iPad、iPadmini與iPhone等3個類 別
- 為了讓iPad、iPadmini與iPhone都有3G上網的功能,這時即可透過箭號的方式套入Internet3G協定
- 最後實作針對iPad、iPadmini與iPhone,實作Internet3G的is3GConnected屬性與connectInternetWith3G方法
iPad.h
#import "Internet3G.h"
#import <Foundation/Foundation.h>
//透過箭號"<>"實作Internet3G協定
@interface iPad : NSObject <Internet3G>
@end
iPadmini.h
#import "Internet3G.h"
#import <Foundation/Foundation.h>
//透過箭號"<>"實作Internet3G協定
@interface iPadmini : NSObject <Internet3G>
@end
iPhone.h
#import "Internet3G.h"
#import <Foundation/Foundation.h>
//透過箭號"<>"實作Internet3G協定
@interface iPhone : NSObject <Internet3G>
@end
iPad.m
#import "iPad.h"
@implementation iPad
//合成is3GConnected屬性
@synthesize is3GConnected = _is3GConnected;
//實作connectInternetWith3G連線方法
-(void) connectInternetWith3G
{
NSLog(@"iPad透過3G連上網路…已連線");
_is3GConnected = YES;
}
@end
iPadmini.m
#import "iPadmini.h"
@implementation iPadmini
//合成is3GConnected屬性
@synthesize is3GConnected = _is3GConnected;
//實作connectInternetWith3G連線方法
-(void) connectInternetWith3G
{
NSLog(@"iPadmini透過3G連上網路…已連線");
_is3GConnected = YES;
}
@end
iPhone.m
#import "iPhone.h"
@implementation iPhone
//合成is3GConnected屬性
@synthesize is3GConnected = _is3GConnected;
//實作connectInternetWith3G連線方法
-(void) connectInternetWith3G
{
NSLog(@"iPhone透過3G連上網路…已連線");
_is3GConnected = YES;
}
@end
4. 測試iPad、iPadmini與iPhone的3G上網功能
- 因iPad、iPadmini與iPhone皆實作Internet3G,因此皆有3G上網的功能
- 皆可connectInternetWith3G方法連結網路,並透過is3GConnected屬性確認是否已經連線
- 在此您會發現,我們透過協定的方式將3G上網功能的相關協定Internet3G,之後只要實作此協定的類別即可擁有3G上網的能力了,就好像掛載特定能力一樣,透過實作協定讓類別擁有特定的能力
#import "iPad.h"
#import "iPadmini.h"
#import "iPhone.h"
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[])
{
@autoreleasepool {
//分別建立iPad、iPadmini、iPhone物件
iPad * pad1 = [[iPad alloc] init];
iPadmini * padmini1 = [[iPadmini alloc] init];
iPhone * phone1 = [[iPhone alloc] init];
//不論是iPad、iPadmini、iPhone物件,
//皆因為實作了Internet3G協定,
//因此都可以透過connectInternetwITH3G連網,
//並且透過屬性is3GConnected確認是否連上了3G。
[pad1 connectInternetWith3G];
NSLog(@"iPad是否已連上3G:%@", pad1.is3GConnected == 1 ? @"YES" : @"NO");
[padmini1 connectInternetWith3G];
NSLog(@"iPadmini是否已連上3G:%@", padmini1.is3GConnected == 1 ? @"YES" : @"NO");
[phone1 connectInternetWith3G];
NSLog(@"iPhone是否已連上3G:%@", phone1.is3GConnected == 1 ? @"YES" : @"NO");
}
return 0;
}
檔案連結:objective_c_protocol.zip
協定的實作,必須與非必須:
- 透過@required,可強制所有協定中的屬性與方法皆必須被實作,此也是預設值,若無作實,則在編譯時會發出警告,告訴您哪些屬性與方法是必須被實作的
- 透過@optional,在此之後宣告的屬性與方法可選擇性的被實作
- 在下列範例,因為@optional關鍵字的關係,is3GConnected是可以選擇性實作的。而connectInternetWith3G則因為@required關鍵字的關係,則是必須實作的
@protocol Internet3G <NSObject>
@optional
@property bool is3GConnected;
@required
-(void) connectInternetWith3G;
@end
協定間的繼承:
- 協定間是可以透過另一個協定進行擴充的,如同類別般可以繼承一樣,如下:
InternetWifi.h
@protocol InternetWifi
-(void) connectInternetWithWifi;
@end
Internet3G.h
協定的多重擴充:
#import "InternetWifi.h"
@protocol Internet3GAndWifi : InternetWifi
@property bool is3GConnected;
-(void) connectInternetWith3G;
@end
- 一個協定是可以擴充至多重協定的,只需要在箭號"<>"中使用逗號","加入另一個協定就ok了,如下:
InternetWifi.h
@protocol InternetWifi
-(void) connectInternetWithWifi;
@end
Internet3G.h
@protocol Internet3G
@property bool is3GConnected;
-(void) connectInternetWith3G;
@end
Internet3GAndWifi.h
類別實作多重協定:
#import "InternetWifi.h"
#import "Internet3G.h"
@protocol Internet3GAndWifi >InternetWifi, Internet3G<
@end
- 一個類別是可以實作多重協定的,只需要在箭號"<>"中使用逗號","加入另一個協定就ok了,如下:
InternetWifi.h
@protocol InternetWifi
-(void) connectInternetWithWifi;
@end
Internet3G.h
@protocol Internet3G
@property bool is3GConnected;
-(void) connectInternetWith3G;
@end
iPad.h
#import "InternetWifi.h"
#import "Internet3G.h"
@interface iPad >InternetWifi, Internet3G<
@end