2014-05-09 78 views
0

ClassA.h需要更多關於Objective-C的多態性和繼承

@interface classA 

-(void)print1; 
-(void)print2; 

@end 

ClassA.m

-(void)print1 { 
    NSLog(@"I am class A 1"); 
} 

-(void)print2 { 
    NSLog(@"I am class A 2"); 
} 

ClassB.h

@interface classB : classA 

-(void)print1; 

@end 

援助ClassB.m

-(void)print1 { 
    NSLog(@"I am class B"); 
} 

AppDelegate.m

ClassA *a1 = [[ClassB alloc]init]; 
    [a1 print1]; 
    [a1 print2]; 

輸出

I am class B 
I am class A 2 

錯誤

ClassB *a1 = [[ClassA alloc]init]; 

問題

ClassBClassA孩子意味着ClassBClassA功能和自身也。但ClassA不知道ClassB是它的孩子。

那麼如何classA *a1 = [[classB alloc]init];工作,並給予上述輸出 和classB *a1 = [[classA alloc]init];是給錯誤

+0

這實際上對大多數(也許是所有)OOP語言都有效。 – Sulthan

回答

1

[[classB alloc]init]
- 這就是你實際創建的對象,而
classA *a1
只是一個宣言,把它簡單的部分,會是什麼「預期」從這個對象是。您的classB是classA的一個子類,因此它具有classA所擁有的全部內容,因此在訪問屬性或使用方法時不會導致錯誤。
在另一方面,當你創建一個ClassA的實例,並將其轉換爲CLASSB:
classB *a1 = [[classA alloc]init]
編譯器會想到這個對象做什麼CLASSB是能夠做到的,而且由於CLASSB是ClassA的擴展,則可能會導致錯誤。

0

對於classA *a1 = [[classB alloc]init];的情況下在Objective-C的工作,因爲,方法是在運行時解析。 [a1 print1]發送消息給a1對象,該對象可以在運行時調用方法print1。即使你可以調用[a1 some_random_method]編譯器會發出警告,但不會出錯。因爲在運行時可能會添加some_random_method

對於第二種情況classB *a1 = [[classA alloc]init];,我想你會得到這個錯誤,因爲這個概念並不全是classAclassB

有可能classB有額外的成員和方法。通過類型化classA對象到classB,您將嘗試訪問那些具有未定義行爲的額外成員和方法。因此,編譯器不支持從classAclassB的隱式類型轉換,並給出錯誤。

但是,您可以明確地將類型classA對象轉換爲classB。在運行時,您可以將此特定的方法(classB)添加到此對象(objective-C支持在運行時添加方法)並調用它們。

+0

感謝您的回覆,但我沒有得到您的第二點。 –

+0

如果有意義,請參閱編輯。 – doptimusprime