2012-04-30 23 views
4

假設我有兩個基類,ContainerGizmo。類Container具有類Gizmo的實例變量。在子類中更改伊維爾的類別(派生類)

現在我的子類Container(叫SubContainer),我也是GizmoSubGizmo)的子類。在SubContainer的一些方法中,我需要發送一條消息給Gizmo沒有但SubGizmo。有沒有什麼方法可以覆蓋伊爾堡的SubGizmoSubContainer,所以我可以發送這些消息?

現在我可以通過將我繼承的伊娃鑄造到SubGizmo每次我需要使用這樣一個屬性或方法。

這就是爲什麼我想要這樣的行爲:我已經有一個可行的遊戲,但我添加的模式越多,維護的難度就越大。如果我想更改/添加將在每種模式下運行的方法;我需要去三個不同的遊戲控制器對象並進行更改。通過子類化,我想將主要的遊戲機制保留在基類中,併爲每種模式創建一個子類。這樣,我在基類中所做的更改將反映在每種模式中。但是每個控制器和遊戲對象都有針對不同模式的新方法,並且它們互相發送消息。這是我的問題出現的地方。

+1

一個程序將不太模糊 – justin

+2

我很高興你似乎贊同我的班級名稱;字母加上一些明星對我來說太難以跟蹤了。 :) –

+0

@JacquesCousteau,更清晰:) – justin

回答

2

只是使用的方法類似這樣的介紹類型的安全性和轉換邏輯:

@interface SubContainer() 

- (SubGizmo *)subGizmo; 
// setter is often unnecessary 
- (void)setSubGizmo:(SubGizmo *)pSubGizmo; 

@end 

@implementation SubContainer 

... 

- (SubGizmo *)subGizmo 
{ 
    Gizmo * ret = self.gizmo; 
    // sanity check the type to ensure this is properly initialized, 
    // or return nil if holding a Gizmo is valid in this context: 
    assert([ret isKindOfClass:[SubGizmo class]]); 
    return (SubGizmo *)ret; 
} 

- (void)setSubGizmo:(SubGizmo *)pSubGizmo 
{ 
    self.gizmo = pSubGizmo; 
} 

- (void)addWater 
{ 
    [self.subGizmo addWater]; 
} 

@end 

然而,匍匐複雜性表明在類型的更多的變化是值得考慮的。

+1

這非常簡潔,我看到我能做的另一件事是做SubGizmo * subg =(SubGizmo *)gizmo;在每個方法的開始都會發送這樣的信息..我認爲他們幾乎做同樣的事情,而你的更全球化。 –

+0

@Kaan yup,當它在多個地方使用時,它會減少很多噪音並減少改變時必須做出的更改次數。 – justin

0

最簡單的方法是在容器中使用SubGizmo,而不是Gizmo。 :-)

但是,如果因爲某些原因無法直接執行此操作,則可以在運行時修改SubContainer(尋找class_addIvarclass_addMethod,我可以在需要時給你一個示例),但那不適用有助於避免Xcode的警告。

+1

你不能在運行時添加一個伊娃到現有的類,class_addIvar只適用於未註冊的類。你可以使用objc_setAssociatedObject雖然 –

+0

@Matthias yes但是然後我想讓A(A ***)的另一個子類擁有另一個屬於B(B ***)的另一個子類的實例,你可以看到我的位置 –

+0

@ Joshua Weinberg:當然,但是我明白OP有控制這個子類。當我嘗試使用點符號訪問屬性時, – Matthias

1

只需使用類型id爲您的伊娃,你只需要包含適當的頭文件,以避免警告。

+0

不起作用。我認爲每次訪問基類沒有的東西時,我都會堅持投射到想要的子類。感謝您的幫助 –

-2

你canu使用NSNotifications發送更新到所有的遊戲控制器。