2011-09-22 87 views
10

我有兩個類,名爲ParentChild,如下所示。 ParentChild的超類我可以使用關鍵字super從它的子類調用超類的方法。是否有可能從它的超類調用一個子類的方法?從其超類調用子類的方法

Child.h

#import <Foundation/Foundation.h> 
#import "Parent.h" 

@interface Child : Parent { 

} 

- (void) methodOfChild; 

@end 

Child.m

#import "Child.h" 

@implementation Child 

- (void) methodOfChild { 

    NSLog(@"I'm child"); 

} 

@end 

Parent.h:

#import <Foundation/Foundation.h> 

@interface Parent : NSObject { 

} 

- (void) methodOfParent; 

@end 

Parent.m:

#import "Parent.h" 

@implementation Parent 

- (void) methodOfParent { 

    //How to call Child's methodOfChild here? 

} 

@end 

導入 「Parent.h」 在應用程序委託的.m文件頭。

應用程序委託的application:didFinishLaunchingWithOptions:方法..

Parent *parent = [ [Parent alloc] init]; 

[parent methodOfParent]; 

[parent release]; 
+7

是的,這在技術上是可行的,但這種設計有味道。特別糟糕。超類不應該知道他們的子類。 – 2011-09-22 13:34:53

+0

我想在從swift中調用的時候實現相同的功能,在這種層次結構中無法識別方法。任何人都可以告訴如何從第一次調用初始化Swift類時獲得相同的結果? – NaXir

回答

58

你可以像Objective C的方法分派是所有動態。只需撥打[self methodOfChild]即可,這可能會生成一個編譯器警告(您可以通過將self轉換爲id來保持沉默)。

但是,對於善良的愛,不要這樣做。父母應該爲孩子提供,而不是孩子爲他們的父母。知道子類新方法的父母是一個巨大的設計問題,在繼承鏈上產生了錯誤的強耦合。如果父母需要它,爲什麼它不是父母的方法?

+1

奇妙的書面和正確的答案。獎勵! – sosborn

+7

可能起源海報正在思考一個C++風格的抽象基類(即定義方法但不提供實現的類),正確的建議是在父類中提供空實現,讓孩子覆蓋他們當且僅當它是相關的? – Tommy

+0

感謝您的好信息。 – Confused

2

super表示「調用派生於父類的方法」,所以可以在子類中使用super,因爲子類只有一個父類。儘管一個類可以有許多_sub_classes,那麼在一般情況下,你怎麼知道要調用哪個方法? (因此,沒有關於sub關鍵字的東西。)

但是,在您的示例中,您有兩個單獨的方法。沒有什麼阻止你說(假設你有很好的理由做這樣的事情!),父,

- (void) methodOfParent { 
    [self methodOfChild]; 
} 
+2

指出_why_答案不正確很有幫助。碰巧,我的不是:obj-c動態發送,'super'意思是「從我父母的方法字典開始執行方法查找」,你可能有一個很好的理由去做一些看起來很可怕的事情。 –

6

從技術上講,你可以做到這一點。但我建議你改變你的設計。你可以聲明一個協議,並讓你的子類採用該協議。然後你可以檢查孩子是否從超類中採用該協議並從超類中調用該方法。

+0

感謝您的信息.. – Confused

+1

您能否提供/分享一些示例代碼來完成協議? – Confused

5

您可以使用此:

Parent.m

#import "Parent.h" 

@implementation Parent 

- (void) methodOfChild { 

    // this should be override by child classes 
    NSAssert(NO, @"This is an abstract method and should be overridden");  
} 

@end 

家長知道孩子和孩子有關於如何實現功能的選擇。

0

如果你超級有多個潛艇然後再爲這一個特定的 子的方法

if ([super isKindOfClass:[specificsub class]]) { 
       [specificsub methodName]; 
      } 

如果你的超級正在處理該對象(即子),因此子的方法 登錄將被稱爲另一種方式是在你的超級類

super *some = [[sub alloc] init]; 
[some methodName]; 
0

這可以通過使用子類中的方法來完成。這是在父類中創建一個方法,並在子類中使用相同的方法。