在子类中更改伊维尔的类别(派生类)
假设我有两个基类,Container
和Gizmo
。类Container
具有类Gizmo
的实例变量。在子类中更改伊维尔的类别(派生类)
现在我的子类Container
(叫SubContainer
),我也是Gizmo
(SubGizmo
)的子类。在SubContainer
的一些方法中,我需要发送一条消息给Gizmo
没有但SubGizmo
。有没有什么方法可以覆盖伊尔堡的SubGizmo
SubContainer
,所以我可以发送这些消息?
现在我可以通过将我继承的伊娃铸造到SubGizmo
每次我需要使用这样一个属性或方法。
这就是为什么我想要这样的行为:我已经有一个可行的游戏,但我添加的模式越多,维护的难度就越大。如果我想更改/添加将在每种模式下运行的方法;我需要去三个不同的游戏控制器对象并进行更改。通过子类化,我想将主要的游戏机制保留在基类中,并为每种模式创建一个子类。这样,我在基类中所做的更改将反映在每种模式中。但是每个控制器和游戏对象都有针对不同模式的新方法,并且它们互相发送消息。这是我的问题出现的地方。
只是使用的方法类似这样的介绍类型的安全性和转换逻辑:
@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
然而,匍匐复杂性表明在类型的更多的变化是值得考虑的。
这非常简洁,我看到我能做的另一件事是做SubGizmo * subg =(SubGizmo *)gizmo;在每个方法的开始都会发送这样的信息..我认为他们几乎做同样的事情,而你的更全球化。 –
@Kaan yup,当它在多个地方使用时,它会减少很多噪音并减少改变时必须做出的更改次数。 – justin
最简单的方法是在容器中使用SubGizmo,而不是Gizmo。 :-)
但是,如果因为某些原因无法直接执行此操作,则可以在运行时修改SubContainer(寻找class_addIvar
或class_addMethod
,我可以在需要时给你一个示例),但那不适用有助于避免Xcode的警告。
你不能在运行时添加一个伊娃到现有的类,class_addIvar只适用于未注册的类。你可以使用objc_setAssociatedObject虽然 –
@Matthias yes但是然后我想让A(A ***)的另一个子类拥有另一个属于B(B ***)的另一个子类的实例,你可以看到我的位置 –
@ Joshua Weinberg:当然,但是我明白OP有控制这个子类。当我尝试使用点符号访问属性时, – Matthias
只需使用类型id为您的伊娃,你只需要包含适当的头文件,以避免警告。
不起作用。我认为每次访问基类没有的东西时,我都会坚持投射到想要的子类。感谢您的帮助 –
你canu使用NSNotifications发送更新到所有的游戏控制器。
一个程序将不太模糊 – justin
我很高兴你似乎赞同我的班级名称;字母加上一些明星对我来说太难以跟踪了。 :) –
@JacquesCousteau,更清晰:) – justin