AS3覆盖addChild(),测试类型

时间:2010-08-02 02:11:52

标签: actionscript-3

这适用于我,但它在as3最佳实践方面看起来是正确的。如果失败则返回null是否正确?

        override public function addChild(child:DisplayObject):DisplayObject {
        if(child is Screen) {
            super.addChild(child);
            return child;
        }

        return null;
    }

3 个答案:

答案 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