我們可以通過對父類的繼承實現一定的擴展,繼承主要有以下幾種典型的用法:
1 代碼複用。.兩個類有部分相同的代碼,那相同的部分我們就沒必要去複製粘貼,完全就可以把公共的部分放在父類中,子類去繼承,只需要實現一次相同的部分即可。
2.創建協議類。父類爲子類規定了一些方法,哪怕是空的,但我們可以默認爲父類爲他的子類創建了一種協議,當不同的類實現同名的方法的時候,程序就可以採用多態的設計。
3.通用性能的發佈。程序員可以定義一些基本的、通用的、可以解決某些問題的類,但是沒有處理代碼,那麼其他的程序員可以創建子類來繼承並且滿足特定的需求。
4.需要對現有邏輯進行輕微改動。例如有個類在程序中的工作表現良好,但是另一個程序員想要修改其中的某些參數,那麼他就可以繼承這個類,並且在子類中修改而無需涉及到父類。
5.功能預覽。子類可以幫助我們進行選擇測試,實現父類的一些方法,
還有一個重點就是要記住,Obj-C中的繼承是單繼承,不支持多繼承。
在Objective-C中super是指向直接父類的指針,而self是指向本身的指針,self就相當於java中的this指針。在OC中寫類時可以在@implementation中定義哪些在@interface中無相應聲明的方法,但這個方法是私有的,僅在類的實現中使用。
在Objectiv-C中幾乎所有的類都是繼承自NSObject類,NSObject類中存在大量功能強大的方法。下面對NSObject類中的各種方法進行試驗和介紹:
1. +(void) load; 類加載到運行環境時調用該方法
測試:在子類中重寫load方法來進行測試, 當重寫完load方法,在mian方法中不需要任何實例化任何對象,當類被加載時load就會別調用.load是類方法,可以直接被類調用。
//重寫NSObject中的load方法
+(void) load
{
NSLog(@"ObjectTest中的load方法被調用啦!!");
}
運行結果:2014-07-30 08:58:31.704 HelloOC[550:303] ObjectTest中的load方法被調用啦!!
2. +(void) initialize;
第一次使用該類時調用該方法,第二次就不調用了
測試:重寫initalize方法
//重寫initialize方法,會在類第一次使用時調用
+(void) initialize
{
NSLog(@"initialize方法被調用了(類第一次被實例化)!");
}
運行結果:
2014-07-30 09:27:53.767 HelloOC[624:303] load方法被調用啦!!
2014-07-30 09:27:53.769 HelloOC[624:303] initialize方法被調用了(類第一次被實例化)!
3. +(id) alloc: 返回一個已經分配好的內存對象;
-(id) init: 對已經分配了內存的實例進行初始化;
new同時調用了alloc 和 init
demo: Object *object = [[Object alloc] init];
可以在子類中把alloc進行重寫,然後觀察運行情況
//重寫alloc方法
+(id) alloc
{
NSLog(@"alloc函數被調用啦");
return [super alloc];
}
//重寫init
-(id) init
{
NSLog(@"init被調用了");
self = [super init];
return self;
}
測試方法一個用alloc和init實例化類,一個用new實例化類:
//第一次使用ObjectTest類
ObjectTest *o1 = [[ObjectTest alloc] init];
//第二次使用ObjectTest類
ObjectTest *o2 = [ObjectTest new];
運行結果:
2014-07-30 09:59:58.991 HelloOC[689:303] load方法被調用啦!!
2014-07-30 09:59:58.993 HelloOC[689:303] initialize方法被調用了(類第一次被實例化)!
2014-07-30 09:59:58.993 HelloOC[689:303] alloc函數被調用啦
2014-07-30 09:59:58.993 HelloOC[689:303] init被調用了
2014-07-30 09:59:58.994 HelloOC[689:303] alloc函數被調用啦
2014-07-30 09:59:58.994 HelloOC[689:303] init被調用了
4.-(void)dealloc 釋放對象自身所佔有的內存;
5. -(Class)class 或者 +(Class)class 返回當前對象的所屬類;
-(Class)superclass 或者 +(Class)superclass返回當前類的父類
//返回當前對象所對應的類
NSString *className =(NSString *) [self class];
NSLog(@"%@類的display方法", className);
//返回當前對象所對應的父類
NSString *superClassName = (NSString *) [self superclass];
NSLog(@"%@類的父類是%@", className, superClassName);
6、-(BOOL)isKindOfClass : (Class)aClass
判斷某個實例是否屬於某個類或者子類的對象
事例代碼如下:
//isKindOfClass的用法
BOOL b = [o2 isKindOfClass:[ObjectTest class]];
if (b == YES) {
NSLog(@"o2是ObjectTest類的對象");
}
7.-(BOOL)isMemberOfClass:(Class)aClass; 只能判斷某個實例是否屬於某個類,不能判斷是否屬於某個父類;
//isMemberOfClass
BOOL result = [o2 isMemberOfClass:[NSObject class]];
if (result == NO) {
NSLog(@"isMemberOfClass不能判斷是否爲NSObject子類的對象");
}
8.-(NSString *) description; 返回字符串形式對象的描述,方便調試
//description
NSString *descript = [o2 description];
NSLog(@"%@", descript);
輸出結果: <ObjectTest: 0x100206650>
9.-(NSUInteger) hash;
返回對象的哈希值;
//hash的用法
NSUInteger hash = [o2 hash];
NSLog(@"%p", hash);
輸出結果:2014-07-30 11:40:35.685 HelloOC[1130:303] 0x100107b70
10.-(BOOL) isEqual:(id)object; 比較兩個對象是否相同,默認是使用地址進行比較的,且hash值一定要相同
//isEqual的用法
NSString *str1 = @"111";
NSString *str2 = str1;
if ([str2 isEqual:str1] == YES)
{
NSLog(@"str2 == str1");
}
else
{
NSLog(@"str2 != str1");
}
Objective-C中的繼承
繼承是is-a的關係,比如貓咪是一個動物,那麼動物是父類,而貓咪是動物的子類。子類具有父類的屬性和 行爲,以及自身的屬性和行爲,也就是說“父類更一般,子類更具體”。