嗯,現在的iPad只能透過wifi上網,現在我要加上3G上網打電話的功能,這要如何作到?! 難到我要重新設計一個新的iPad嗎?! 原先作好的功能,如:開關機、播影片不就要重作一次? |
我是類別class, 您可以透過繼承的方式, 繼承現有iPad的功能, 而後在加上您所需的功3G上網功能就可以了。 |
1. 建立iPad類別
- 新增Objective-C class檔案,取名為iPad
2. 提供iPad的Wifi上網功能
- 於iPad.h建立connectWithWifi方法
- 並於iPad.m檔實作connectWithWifi方法
iPad.h
#import <Foundation/Foundation.h>
@interface iPad : NSObject
//iPad提供Wifi上網的功能
-(void) connectInternetWithWifi;
@end
iPad.m
#import "iPad.h"
@implementation iPad
-(void) connectInternetWithWifi
{
NSLog(@"透過Wifi連上網路…已連線");
}
@end
3. 建立iPad3G,並繼承自iPad
- 為了讓iPad3G可以擁有iPad Wifi上網的功能,這時可在建立iPad3G時,於Sub class of欄位填入iPad,以繼承iPad的Wifi上網功能
- 建立好後,在程式中您會iPad3G冒號":"後面是iPad,這就是繼承自iPad的意思
#import "iPad.h"
//iPad3G後方的冒號":"即是所要繼承的類別名稱,
//如此iPad3G即繼承自iPad這個類別,
//讓iPad3G繼承iPad的功能。
@interface iPad3G : iPad
@end
4. 提供iPad3G的3G上網功能
- 於iPad3G.h加上connectInternetWith3G方法
- 於iPad3G.m實作connectInternetWith3G方法
- 如此即可讓iPad3G擁有3G上網的功能了
iPad3G.h
#import "iPad.h"
//iPad3G後方的冒號":"即是所要繼承的類別名稱,
//如此iPad3G即繼承自iPad這個類別,
//讓iPad3G繼承iPad的功能。
@interface iPad3G : iPad
//iPad3G提供3G上網的功能
-(void)connectInternetWith3G;
@end
iPad3G.m
#import "iPad3G.h"
@implementation iPad3G
-(void)connectInternetWith3G
{
NSLog(@"透過3G連上網路…已連線");
}
@end
5. iPad3G的Wifi與3G上網
- 最後在使用iPad3G時,您會發現除了可以使用定義在iPad3G的connectInternetWith3G外,還可使用connectInternetWithWifi上網,而這即是透過繼承的功能,繼承iPad Wifi上網的功能
#import <Foundation/Foundation.h>
#import "iPad3G.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
iPad3G * ipad3g = [[iPad3G alloc] init];
//這是繼承自iPad的方法,並未於iPad3G類別中定義,但透過繼承即可使用此方法
[ipad3g connectInternetWithWifi];
[ipad3g connectInternetWith3G];
}
return 0;
}
檔案連結:objective_c_inheritance.zip
屬性與實體變數也可以繼承:
- 屬性也可透過繼承的方式,讓子類別擁有此屬性
- 實體變數也可以繼承,不過特別要注意的是存取的權限不可為@private,而必預是@protected、@package或@public
所有類別皆繼承自NSObject:
- 您會發現,當你建立一個類別的時候,系統會自動幫你繼承自NSObject,沒錯,在objective-c中,所有的類別皆會繼承自NSObject,且至少繼承自NSObject
- 多型在物件導向中是非常重要的觀念,但在Objective-C中就沒有那麼強烈了,因為Objective-C的動態語言讓型別變的不是那麼明顯,而是動態決定是否可執行特定型別的方法,後續會介紹id型別如何的表示動態語言這一部份
- 多型的意思指的是物件可擁有多種型別,這讓一個物件擁有多重身份,比如iPad3G因繼承自iPad,因此也擁有iPad的型別,因此可以透過小括號加上型別轉型為對應的型別,進行對應型別的操作,如下程式:
#import <Foundation/Foundation.h>
#import "iPad3G.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
iPad3G * ipad3G1 = [[iPad3G alloc]init];
//因iPad3G繼承自iPad,
//因此擁有iPad的型別、擁有iPad的身份,
//因此可以透過小括號加型別轉型成iPad,
//以視為iPad進行操作。
iPad * ipad1 = (iPad*) ipad3G1;
[ipad1 connectInternetWithWifi];
}
return 0;
}
- 繼承時,若繼承的方法不合乎預期的操作時,則可透過改寫的方式去修正繼承的方法,如iPad3G繼承自iPad的connectWithWifi方法,需改成判斷是否已透過3G連網,若是的話則先關閉3G網路在透過Wifi連網,這時可在.m檔案再次宣告繼承的方法connectWithWifi以進行方法的改寫
- 當然,改寫的事實是不會改變的,因此不論如何轉型皆會是使用改寫後的方法
iPad3G.h
iPad3G.m
@interface iPad3G:iPad
@property BOOL is3GConnected;
//iPad3G提供3G上網功能
-(void)connectInternetWith3G;
@end
iPad3G.m
#import "iPad3G.h"
@implementation iPad3G
-(void)connectInternetWith3G
{
_is3GConnected = YES;
NSLog(@"透過3G連上網路…已連線");
}
@synthesize is3GConnected = _is3GConnected;
//改寫,修正Wifi上網的功能,
//讓iPadair可判斷是否以3G連網,
//若以3G連網則關閉3G,
//在以Wifi連網,
//而改寫的方式後簡單,
//就是方法在宣告一次即可。
-(void) connectInternetWithWifi
{
if(_is3GConnected == YES)
{
_is3GConnected = NO;
NSLog(@"關閉3G網路…");
}
NSLog(@"iPad3G透過Wifi連上網路…已連線");
}
@end
main.m
#import <Foundation/Foundation.h>
#import "iPad3G.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
iPad3G * pad3g = [[iPad3G alloc] init];
[pad3g connectInternetWith3G];
[pad3g connectInternetWithWifi];
}
return 0;
}