Обратное обращение к родительскому объекту из дочернего объекта

StackOverflow https://stackoverflow.com/questions/60051

  •  09-06-2019
  •  | 
  •  

Вопрос

Мой вопрос касается наилучшей практики доступа к родителю дочернего объекта.Допустим, класс создает экземпляр другого класса, на этот экземпляр класса теперь ссылается объект.Как лучше всего обратиться к родительскому объекту из этого дочернего объекта?В настоящее время я знаю пару способов, которые часто использую, но я не уверен, а) есть ли лучший способ сделать это или Б) какой из них лучше.

Первый метод — использовать getDefinitionByName, который не будет создавать экземпляр этого класса, но позволит получить доступ ко всему, что внутри него объявлено публично.

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

А затем сослаться на эту переменную на основе ее родительской и дочерней иерархии.
Пример, если дочерний элемент пытается сослаться на класс, который находится на два уровня выше него самого:

_class(parent.parent).function();

Кажется, это работает нормально, но вам необходимо знать уровень, на котором находится дочерний элемент, по сравнению с уровнем родителя, к которому вы пытаетесь получить доступ.

Я также могу получить следующий оператор для отслеживания [имя класса объекта] в выходных данных Flash.

trace(Class);

Я не на 100% реализую эту строку, я не рассматривал ее как способ ссылаться на объект за пределами текущего объекта, в котором я нахожусь.

Другой метод, который я видел, — это просто передать ссылку на это в объект класса, который вы создаете, и просто перехватить ее с помощью аргумента конструктора.

var class:Class = new Class(this);  

а затем в файле классов

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

Однако эта ссылка также требует от вас вернуться к использованию иерархии от дочернего к родительскому.

Я также мог бы импортировать этот класс, а затем использовать прямой путь к файлу для ссылки на метод внутри этого класса, независимо от того, является ли он родительским или нет.

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

Конечно, здесь отношения родитель-потомок не имеют значения, поскольку я обращаюсь к методу или свойству напрямую через импортированный класс.

Я просто чувствую, что упускаю здесь что-то действительно очевидное.По сути, я ищу подтверждение, являются ли эти способы ссылки на родителя правильными, и если да, то какой из них наиболее идеален, или я упускаю из виду что-то еще?

Это было полезно?

Решение

Обычно хорошо иметь класс как отдельный экземпляр и уменьшить тесную связь с чем-то другим (как в данном случае, с родительским классом).Если вы сделаете что-то вроде родительского.doSomething(), невозможно использовать этот класс в контейнере, в котором нет метода doSometing().Я думаю, что определенно лучше передать все, что может понадобиться классу, а затем внутри класса больше не нужно делать никаких родительских действий и т. д.

При этом, если в будущем вы захотите изменить структуру, очень легко просто передать новую ссылку;реализация дочернего класса вообще не должна меняться.

Третий вариант, который у вас есть, также сильно отличается: он обращается к статическому методу уровня класса (вам не нужно вводить весь путь к классу при доступе к этому методу), а не к методу экземпляра, как в первых двух.

Другие советы

В общем, если вам нужно, чтобы ребенок общался с родителем, вам следует рассмотреть возможность того, чтобы он делал это путем трансляции событий.Это отделяет дочерний элемент от родителя и позволяет другим классам работать с дочерним элементом.

Я бы не рекомендовал передавать ссылку на родительский класс в дочерний.

Вот простой пример (я протестировал/скомпилировал его, поэтому могут быть некоторые опечатки).

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

    }
}

В большинстве случаев вы отправляете пользовательские события и передаете вместе с ними данные.

По сути:

Родитель имеет ссылку на Дочерний элемент и общается посредством вызовов методов.Дочерний элемент не имеет ссылки на Родителя и общается (с кем-либо) посредством отправки событий.

надеюсь, это поможет...

Майк Чемберс

mesh@adobe.com

Я всегда использовал ваш второй метод, передавая указатель на родительский объект дочернему объекту и сохраняя этот указатель в переменной-члене дочернего класса.Мне кажется, это самый простой способ общения ребенка с родителем.

Мне нравится передавать родительский элемент в качестве интерфейса (чтобы класс мог содержаться в любом родительском элементе, реализующем этот интерфейс) или реализовывать ссылку как указатель/делегат события/функции, к которому может подключиться родительский элемент.

Мне нравится создавать глобальный класс для обработки ссылок на классы, к которым должен иметь доступ любой другой класс, не обязательно дочерний.

Глобальный класс просто состоит из статических геттеров и сеттеров, например:

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.например

ParentClass(parent).parentFunction();

Я точно знаю, что это работает, если ParentClass является классом документа.Поскольку класс документа всегда является первым элементом в списке отображения, это работает:

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

В моем случае они оба были членами одного пакета, поэтому мне даже не пришлось ничего импортировать.Я не проверял его при всех обстоятельствах, но он работал, когда мне это было нужно.

Конечно, «родитель» и «getChild...» работают, только если эти объекты находятся в DisplayList, но для меня этого было достаточно.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top