从子对象引用回父对象

时间:2020-03-05 18:52:34  来源:igfitidea点击:

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

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

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

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

_class(parent.parent).function();

这似乎可以正常工作,但是我们需要知道孩子所处的水平与我们尝试访问的父母所处的水平相比。

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

trace(Class);

我不是那条线的实现的100%参与者,我没有说服它作为引用当前所在对象之外的对象的一种方式。

我见过的另一种方法是将对此的引用简单地传递到我们正在创建的类对象中,然后使用构造函数参数捕获它

var class:Class = new Class(this);

然后在Class文件中

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

该参考还要求我们通过使用子级到父级层次结构来逐步备份。

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

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

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

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

解决方案

回答

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

回答

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

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

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

回答

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

回答

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

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

private static const class:Class;

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

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

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

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

回答

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

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

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

//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");
        }

    }
}

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

基本上:

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

希望有帮助...

迈克·钱伯斯

[email protected]

回答

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

ParentClass(parent).parentFunction();

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

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

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

当然,只有这些对象在DisplayList中时," parent"和" getChild ..."才起作用,但这对我来说已经足够了。