Flash as3引用带子的父变量

时间:2011-10-31 17:24:13

标签: flash actionscript-3

我很难掌握孩子如何引用父母的变量。

这是我的Main.as:

package
  {
        import flash.display.MovieClip;

    public class Main extends MovieClip
    {
        public var i;
        public var child: Child;

        public function Main()
        {
            i = 4;
            child = new Child;
        }
    }
}

这是我的Child.as:

package
{
    import flash.display.MovieClip;

    public class Child extends MovieClip
    {
        public function Child()
        {
            trace([parent as MovieClip].i);
        }
    }
}

child正在尝试访问父级中的公共变量i,但是我收到错误:

未定义

使用trace(MovieClip(parent).i)代替我:

  

TypeError:错误#1009:无法访问null的属性或方法   对象参考。在Main()的Child()

我觉得我错过了一些非常基本的东西(就像我在构建孩子时没有设定价值一样)但是我无法弄清楚是什么。

非常感谢澄清。

2 个答案:

答案 0 :(得分:1)

parent的{​​{1}}属性在通过DisplayObjectDisplayObjectContainer添加到另一个.addChild()时设置。这些调用由Flash UI隐式进行,以将子项添加到可见对象。

所以你正在做的事情有些不对劲,有些是关于.addChildAt()如何在flash中工作的误解,还有一些是语法问题。

当您致电DisplayObjects时,您正在调用new Child()类'构造函数,在您的情况下:

Child

此时,它已将 作为子项添加到public function Child() { trace([parent as MovieClip].i); } 。只需在父类中将其命名为DisplayObjectContainer,就不会创建此关系。所以在这种情况下,构造函数child内部将始终为null,因为它只是创建this.parent类的新实例,它不知道任何“父”

这里还有一个非常大的语法问题。您正在进行Child强制转换(如果类型不兼容,将返回as)。但是,在这种情况下,null已经parent,但您正在使用null,这是写文字[]的方法。因此,您实际上是在创建一个新的Array,其中包含一个Array元素。然后,您尝试在null上获取名为i的属性,而不是父级。

显然,这不是你想做的......总之。你可能意味着这样的事情:

Array

但即使这样也不对,因为public function Child() { trace((parent as MovieClip).i); } 不是i上的属性,它是您的子类MovieClip上的属性。所以真的可能意味着:

Main

但是这仍然会失败,因为正如我之前所说,public function Child() { trace((parent as Main).i); } 因为它尚未作为一个孩子添加。

请考虑以下代码:

parent == null

public class Main extends MovieClip
{
    public var i;
    public var child:Child;

    public function Main()
    {
        i = 4;
        child = new Child();
        child.doWork();
        this.addChild(child)
        child.doWork();
    }
}

这应该调用方法public class Child extends MovieClip { public function Child() { doWork(); } public function doWork() { if(parent == null) { trace("No parent yet.") return; } var mainParent:Main = (parent as Main); if(mainParent == null) { trace("Parent isn't a instance of Main!") return; } trace(mainParent.i); } } 三次:一次在子的构造函数中,然后在添加到显示树之前,最后添加到显示树之后。并且希望它更有意义,看到它的工作方式如此。

还有很多东西需要学习,特别是关于事件,事件冒泡以及doWork()DisplayObjects如何相关/嵌套。但也许这会让你朝着正确的方向发展。只要知道DisplayObjectContainers只是parent的一个属性(DisplayObject的一个祖先和flash中的许多其他类)。了解这些类如何相互协作,并使用您自己的功能扩展它们,是真正理解闪存的关键。

答案 1 :(得分:0)

基本上,在调用方法addChild之前,不会设置父级:

public class Main extends MovieClip
{
    public var i;
    public var child: Child;

    public function Main()
    {
        i = 4;
        child = new Child;
        addChild(child);
    }
}

当然这意味着父级不可用,并且在构造函数中将是未定义的。我有时会将我希望将子项添加到构造函数参数中的父项传递,以便在适当的情况下简化与x / y位置的添加。

public class Child extends MovieClip
{
    public function Child(targetParent:DisplayObjectContainer = null, xpos:Number = 0, ypos:Number =  0)
    {
      if (targetParent != null)
     {
        targetParent.addChild(this);
     }

     this.x = xpos;
     this.y = ypos;
    }
}