关于Flash:从子对象返回父对象

关于Flash:从子对象返回父对象

Referencing back to the parent from a child object

我的问题与访问子对象的父对象的最佳实践有关。假设一个类实例化了另一个类,该类实例现在被一个对象引用。从该子对象中,引用回父对象的最佳方法是什么?目前,我知道我经常使用的几种方法,但是我不确定A)有更好的方法还是B)哪种方法更好?

第一种方法是使用getDefinitionByName,它不会实例化该类,但允许访问其内部公开声明的任何内容。

1
_class:Class = getDefinitionByName("com.site.Class") as Class;

然后基于其父级到子级层次结构引用该变量。
例如,如果孩子正在尝试引用一个比自身高两个级别的类:

1
_class(parent.parent).function();

这似乎很好,但是您需要知道孩子的水平与您尝试访问的父母的水平相比。

我还可以获得以下语句,以将[object ClassName]跟踪到Flash的输出中。

1
trace(Class);

我不是100%的执行该行,我没有说服它作为引用当前所在对象之外的对象的一种方法。

我见过的另一种方法是将对此的引用简单地传递到您正在创建的类对象中,并使用构造函数自变量进行捕获

1
var class:Class = new Class(this);

,然后在Class文件中,

1
2
3
public function Class(objectRef:Object) {
    _parentRef = objectRef;
}

该参考文献还要求您逐步使用子级到父级的备份。

我也可以导入该类,然后使用直接文件路径引用该类内部的方法,而不管其父级与否。

1
2
import com.site.Class;
com.site.Class.method();

当然,父子关系是无关紧要的,因为我直接通过导入的类访问方法或属性。

我只是觉得我在这里确实缺少一些明显的东西。我基本上是在寻求确认,如果这些是引用父级的正确方法,如果是,那是最理想的,还是我在忽略其他东西?


通常,如果您需要一个孩子与父母沟通,您应该通过广播事件来看看是否这样做。这样可以使子代与父代分离,并使其他类与该子代一起工作成为可能。

我不建议将对父类的引用传递给子类。

这是一个简单的例子(我已经测试/编译过这个,所以可能会有一些错别字)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
//Child.as
package
{
    import flash.events.EventDispatcher;
    import flash.events.Event;

    public class Child extends EventDispatcher
    {
        public function doSomething():void
        {
            var e:Event = new Event(Event.COMPLETE);
            dispatchEvent(e);
        }

        public function foo():void
        {
            trace("foo");
        }
    }
}


//Parent.as
package
{
    import flash.display.Sprite;
    import flash.events.Event;
    public class Parent extends Sprite
    {
        private var child:Child;
        public function Parent():void
        {
            c = new Child();
            c.addEventListener(Event.COMPLETE, onComplete);
            c.foo();//traces foo

            c.doSomething()
        }

        public function onComplete(e:Event):void
        {
            trace("Child broadcast Event.COMPLETE");
        }

    }
}

在大多数情况下,您将调度自定义事件并与它们一起传递数据。

基本:

父母引用了Child并通过方法调用进行通信。
子级没有对父级的引用,而是通过调度事件(与任何人)进行通信。

希望有帮助...

麦克·钱伯斯

mesh@adobe.com


最好将类作为自己的实例,并减少与其他对象的紧密耦合(在这种情况下,它是父级)。如果您执行类似parent.doSomething()之类的操作,则无法在没有doSometing()方法的容器中使用该类。我认为最好传入任何类可能需要的内容,然后再在该类内部不再执行任何parent.parent等。

有了这个,如果您将来想更改结构,只需传递一个新的引用就很容易了;子类的实现根本不需要更改。

这里的第三种选择也非常不同,它访问一个类级别的静态方法(访问该方法时不必键入整个类路径),而不是实例方法。前两个。


我喜欢设置一个全局类来处理对需要由任何其他类(不一定是子类)访问的类的引用。

全局类仅由静态getter和setter组成,如下所示:

1
2
3
4
5
6
7
8
private static const class:Class;

public static function setClass(_class:Class){
class = _class;
}
public static function getClass(void):Class{
return class;
}

这样做的好处是您不必导入要从全局类返回的类,只需导入全局类本身。

需要引用的类将自身添加到全局列表中。
另一个很酷的事情是,您可以轻松地从此集中位置调度事件。

大多数时候,如果一个类需要由子类或任何其他类引用,我会通过一个接口来实现。


我喜欢将父级作为接口传递(因此该类可以包含在实现该接口的任何父级中)或将引用实现为父级可以挂接到的事件/函数指针/委托。


我一直使用第二种方法,将指向父对象的指针传递给子对象,并将该指针存储在子类的成员变量中。对我来说,这似乎是孩子与父母沟通的最简单方法。


如果这些对象在DisplayList中,那么您还有更多选择。如果我在子类中具有ParentClass和ChildClass,则在将请求强制转换为ParentClass时,您似乎可以访问父类。例如

1
ParentClass(parent).parentFunction();

我肯定知道ParentClass是Document Class是否可以工作。由于文档类始终是显示列表中的第一项,因此可以:

1
ParentClass(stage.getChildAt(0)).parentFunction();

就我而言,他们都是同一个程序包的成员,所以我什至不需要导入任何东西。我尚未在所有情况下都进行过测试,但是在需要时它可以工作。

当然,\\'parent \\'和\\'getChild ... \\'仅在这些对象位于DisplayList中时才起作用,但这对我来说已经足够了。


推荐阅读