这适用于我,但它在as3最佳实践方面看起来是正确的。如果失败则返回null是否正确?
override public function addChild(child:DisplayObject):DisplayObject {
if(child is Screen) {
super.addChild(child);
return child;
}
return null;
}
答案 0 :(得分:1)
我不明白为什么不。我在实践中从未实际使用过addChild的返回值。您需要某种方式来了解孩子是否已被添加,以便您可以使用:
if (!addChild(child))
{
//couldn't be added
}
而不是
if (child is Screen)
{
addChild(child);
}
else
{
// couldn't be added
}
或者您可以在覆盖中抛出错误并捕获它,如果它不是Screen的实例。
如果它适合你,我认为这根本不是最佳实践问题。
答案 1 :(得分:0)
我看到了几个选项,没有一个感觉完全“正确”。
我认为最好的解决方案在Actionscript中是不可能的(我认为这在其他语言中是允许的)。也就是说,声明您只接受Screen的实例:
override public function addChild(child:Screen):Screen {
return super.addChild(child);
}
由于那是不可能的,我能想到的其他选择是:
1)抛出错误。
我一般不太喜欢抛出错误,但这里的专家是它匹配扩展类的行为。如果将无效的显示对象传递给addChild,它将抛出。另一方面,这是有效的,因为方法签名告诉您必须传递DisplayObject。在这种情况下,您的方法在某种程度上是“撒谎”,因为它表示它接受DisplayObjects但它实际上只接受Screen的实例。所以你依靠文档(希望)而不是类型系统来告诉用户代码它应该如何使用你的函数。
2)添加一个调用addChild的addScreen方法。
public function addScreen(child:Screen):Screen {
return super.addChild(child) as Screen;
}
这有点类型安全,但是你失去了一些多态性的优点(也许你的代码中不可能/不可行)。也许如果我们有方法重载...但我们不是这样,再次,我想这是一个权衡。
3)运行时类型检查并在失败时返回null。
这就是您的代码所做的事情。它可能会很好。我不喜欢它是我上面提到的:你的方法有点“撒谎”。我不希望一个方法使DisplayObject失败,因为我传递了一个DisplayObject。但有时候,这不是什么大不了的事。
我担心我无法对此作出明确答复。如果可能的话,我想我可能会选择2),但所有这些选项似乎同样有效。我想,在某些时候你必须满足于对你和你的项目更有意义的那个。
答案 2 :(得分:0)
没有好办法,你想做什么。如果您想要所需的行为,则使用合成而不是继承。您要做的是违反Liskov substitution principle。