所以的裝置都變成id了!! 但我手上明明是支援3G的iPad 3G,我想要開啟3G網路,到底開不開的起來啊? |
我是id型別, 沒關係,你只要把你要作什麼事的訊息傳給我, 我會在轉交給實際的存放在這的對應裝置。 |
我是物件Object, 雖然我被當作id看待, 但若我本身就是一個iPad 3G, 那你一定可以開啟3G網路的。 |
1. 建立iPad、iPadmini與iPhone
- 建立iPad、iPadmini與iPhone類別,大致定義如下:
Internet3G.h
#import <Foundation/Foundation.h>
@protocol Internet3G <NSObject>
//協定中,有個是否3G已連結的屬性
@property bool is3GConnected;
//協定中,定義透過3G連結的方法
-(void) connectInternetWith3G;
@end
iPad.h
#import <Foundation/Foundation.h>
@interface iPad : NSObject
-(void) connectInternetWithWifi;
@end
iPadmini.h
#import "iPad.h"
#import "Internet3G.h"
#import <Foundation/Foundation.h>
//透過箭號"<>"實作Internet3G協定
@interface iPadmini : iPad <Internet3G>
@end
iPhone.h
#import "Internet3G.h"
#import <Foundation/Foundation.h>
//透過箭號"<>"實作Internet3G協定
@interface iPhone : NSObject <Internet3G>
@end
2. id型別下透過中括號"[]"傳送訊息,進行Wifi或3G網路連線
- Objective-C是一個動態語言,意思就是執行的方法可以在動態時決定,只要透過中括號"[]"傳送的訊息可以被此物件執行,程式就可以程式動態執行時執行對應的方法
#import <Foundation/Foundation.h>
#import "iPad.h"
#import "iPadmini.h"
#import "iPhone.h"
int main(int argc, const char * argv[])
{
@autoreleasepool
{
iPad * pad1 = [[iPad alloc] init];
iPadmini * padmini1 = [[iPadmini alloc] init];
iPhone * phone1 = [[iPhone alloc] init];
//iPad、iPadmini與iPhone物件皆放在id型別的變數中
id device1 = pad1;
id device2 = padmini1;
id device3 = phone1;
//雖然iPad、iPadmini與iPhone都以當作id型別存放於id變數中,
//但仍可以直接傳訊息叫它們作事,
//這就是objective-c動態執行程式的能力,
//程式會在執行時自動識別是否有此方法可執行,
//若有的話則執行此方法。
[device1 connectInternetWithWifi];
[device2 connectInternetWithWifi];
[device2 connectInternetWith3G];
[device3 connectInternetWithWifi];
[device3 connectInternetWith3G];
}
return 0;
}
檔案連結:objective_c_id_2.zip
id若接收到不能執行的訊息,則程式會中斷:
- Objective-C是一個動態語言,可在執行時在決定執行哪一個方法,但若是傳送的訊息此物件無對應的方法時,程式則會當機中斷,如下範例,iPad僅可透過connectInternetWithWifi上網,若傳送connectInternetWith3G則會出錯中斷程式:
iPad.h
#import <Foundation/Foundation.h>
@interface iPad : NSObject
-(void) connectInternetWithWifi;
@end
#import <Foundation/Foundation.h>
#import "iPad.h"
int main(int argc, const char * argv[])
{
@autoreleasepool
{
iPad * pad1 = [[iPad alloc] init];
id device1 = pad1;
//無法找到對應的方法,程式當機中斷
[device1 connectInternetWith3G];
}
return 0;
}
id與協定:
- id其實可以與協定配合,讓id可以限定裝下的物件必須實作某個協定,只要使用箭號"<>"即可做到
iPadmini * padmini1 = [[iPadmini alloc] init];
id<Internet3G> device1 = padmini1;
- 當然,限定的型別可以是1個以上,只要透過逗號","分隔即可
iPhone * iphone1 = [[iPhone alloc] init];
id<InternetWifi, Internet3G> device1 = iphone1;