2010-09-02 44 views
0

作爲一個例子,當我使用NSMutableDictionary時,我知道它繼承了NSDictionary的所有方法,但是如何知道/相信它已經重寫了這些方法的行爲,如果我想使用NSDictionary方法(例如+dictionaryWithObjectsAndKeys)創建我的可變字典實例?如何知道在NS子類中使用父方法是否安全?

更一般地說,框架的責任是確保子類不會盲目地繼承可能會破壞子類實例的方法(如果使用的話)?或者編碼者有責任知道不使用它們?如果從Rectangle,並通過繼承Square繼承我可以叫

Square *newSquare = [[Square alloc] init]; 
[newSquare setWidth:3 andHeight:6]; //instead of -(void)setSide:(int)side 

我有「破」廣場等方法依賴於寬度等於高度將現在無法正常工作。遊戲的規則是什麼?

回答

0

該規則將只暴露你會允許重寫它的意思,把你的接口放在什麼是真正公開的。必要時明確指出在某個點[super methodName]重寫某個特定的方法調用時。

在你的例子中,你會覆蓋方法- (void)setWidth:(int)width andHeight:(int)height,如果你想要拋出一個錯誤width != height。或者你也可以拋出一個錯誤並強制用戶只使用- (void)setSide:(int)side

例如,你可以這樣做:

// If you want to test and accept cases when width == height 
- (void)setWidth:(int)width andHeight:(int)height { 
    NSAssert(width == height, NSLocalizedString(@"This is a Square. Width has to be height.", nil)); 

    [super setWidth:width andHeight:height]; 

    // Or 

    [self setSide:width]; 
} 

// Or if you want to completely prohibit the usage of the method 
- (void)setWidth:(int)width andHeight:(int)height { 
    NSAssert(NO, NSLocalizedString(@"This is a Square! Please use - (void)setSide:(int)side method.", nil)); 
} 

如果你想扔在編譯時的一些錯誤和警告,你可以在你的方法聲明中使用,一些宏對NSObjCRuntime.h定義。

+0

感謝您的回答;如果我可能要求澄清,當我實施我自己的子類時,這個原則很容易遵循。然而,我仍然有點困惑,關於什麼/哪裏(docs/headers?)這些規則適用於Foundation類。在我的NSMutableDictionary示例中,我知道NSDictionaryCreation類別中的方法是由NSMutableDictionary繼承的,但這是否意味着NSDictionaryCreation類別方法應該被認爲是「公共」的並且可以安全地用於NSMutableDictionary?由於我不是這些班級的創造者,所以我很無奈。 – snackdefend 2010-09-02 05:26:28

+0

這是一個我們需要忍受的問題,因爲我們無法訪問某些類的實現,所以我們只能假定它們實現/尊重他們的所有超類,否則他們會拋出一個錯誤,指出請求的方法不是支持的。 – vfn 2010-09-02 05:46:05

+0

再次感謝。對於我來說,使用這種來自開放的實現語言的操作感覺不太舒服。因此,爲了重述您的答案,也許我可以說「總是測試您的遺傳基金會代碼」? :) – snackdefend 2010-09-02 05:50:55

0

我不會相信父方便方法來調用你的繼承init方法。如果該方法被定義,那麼這樣就不會甚至不知道你的實現

+ (id)dictionaryWithObjectsAndKeys:... 
{ 
    return [[[NSDictionary alloc] initWithObjectsAndKeys:...] autorelease]; 
} 

:例如,字典法可以被定義爲。

您必須創建自己的便利方法。喜歡的東西會在你的MyDictionary實現:

+ (id)myDictionaryWithObjectsAndKeys:... 
{ 
    return [[[MyDictionary alloc] initWithObjectsAndKeys:...] autorelease]; 
} 

-

也...

你或許應該從廣場繼承矩形。繼承是附加的。您可以用一種尺寸(寬度)來描述Square,但對於Rectangle,您有兩種尺寸(寬度,高度)。

+0

我明白答案,但我很困惑和不確定如何NSDictionary方法可以調用一個NSMutableDictionary方法方式(錯誤的繼承方向,對吧?)。我還編輯了我的初始問題,指定我沒有實現可變字典類,實際上我想知道是否可以安全地使用NSDictionaryCreation類別中的NSDictionary的方法實現NSMutableDictionary。同樣,對於從不可變類繼承的NSMutableFoo(數組,字符串等),一切都繼承到可變子類的「公共」? – snackdefend 2010-09-02 05:34:13

+0

糟糕。我改變了一些例子來刪除Mutable的東西。手指有自己的想法。 ...就安全而言 - 不。快速測試將嘗試NSMutableDictionary * md = [NSMutableDictionary dictionary]; NSLog(@「class:%@」,NSStringFromClass([md class]));答案是:不可變的字典。 – 2010-09-02 09:54:42

+0

但是, NSMutableDictionary * md = [NSMutableDictionary dictionary];如果([md isKindOfClass:[NSMutableDictionary class]] && [md respondsToSelector:@selector(removeObjectForKey :)]) NSLog(@「Execution gets here」); 做日誌,所以這些檢查是完全從運行時指針類型檢查完成的(這反映了我對內省機制的理解不夠,因爲我認爲可以在編譯期間等價地檢查非id事物)?我認爲NSStringFromClass()只是顯示字典類集羣依賴使用的內部實現細節。 – snackdefend 2010-09-02 13:15:11

相關問題