Проблема с классом Flash и MovieClip

У меня странная проблема. В Flash CS3 IDE я связал MovieClip с классом SubSimba. Этот класс не расширяет MovieClip (в его основе лежит пакет MovieClip), но вместо этого он расширяет SuperSimba (расширяет MovieClip). Что случается? Я создаю экземпляр SubSimba в своем проекте Flash, и он ведет себя так же, как если бы я вызвал super () внутри конструктора SubSimba: есть ли здесь кто-нибудь, кто понимает, почему?

package {
    import flash.display.*;
    import flash.events.MouseEvent;

    public class SuperSimba extends MovieClip {
        public function SuperSimba() {
            trace('hi from SuperSimba');
        }
        private function doThis(evt:MouseEvent):void {
            // 
        }
    }
}


package {
    import flash.display.*;
    import flash.events.MouseEvent;

    public class SubSimba extends SuperSimba {
        public function SubSimba() {
            trace('hi from SubSimba');
        }
        private function doThis(evt:MouseEvent):void {
            //
        }
    }
}

person Lotus    schedule 17.12.2010    source источник


Ответы (2)


Это поведение по умолчанию.

Что касается того, почему doThis вызывается как для подкласса, так и для супер. Это потому, что суперкласс не имеет ключевого слова virtual в определении метода.

В классе SuperSimba определение метода doThis () должно быть таким:

private virtual function doThis(evt:MouseEvent):void {

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

person Jón Trausti Arason    schedule 17.12.2010

Я не уверен, правильно ли я понял вопрос, но super () в конструкторах всегда вызывается по умолчанию, даже если вы не указываете это явно. Итак, во время создания SubSimba (в начале или в конце, я не уверен) будет вызываться конструктор SuperSimba.

РЕДАКТИРОВАТЬ:

Чтобы объяснить, о чем мы говорим, в комментарии к этому ответу.

Вы должны понимать, что частные функции не могут быть переопределены, и их объем ограничен только тем классом, в котором вы сейчас находитесь. Итак, если у SuperSimba есть doThis(), а у SubSimba doThis(), каждая из этих функций doThis считается отдельной функцией в отдельной области.

Итак, если в SubSimba вы сделаете addEventListener(SOME_EVENT, doThis);, он будет ссылаться на doThis () SubSimba. Он понятия не имеет, что SuperSimba также имеет doThis функцию, потому что это Private и вне области видимости.

То же и с SuperSimba. addEventListener(SOME_EVENT, doThis) в SuperSimba фактически ссылается на doThis, объявленный в SuperSimba, потому что он не имеет представления о том, что объявлен в SubSimba (потому что он частный).

Другими словами, это как если бы функция doThis в SuperSimba была совершенно другой именованной функцией, чем у SubSimba. Приватная функция доступна только тому классу, в котором она находится, а не его родителям и потомкам. Прочтите о модификаторах доступа, если вы запутались.

Учебник: как приватность и наследование с определенными конструкторами могут вас разозлить

У вас есть два класса:

public class Super{
    public function Super(){ //THIS IS CONSTRUCTOR OF SUPER
        addEventListener(SOME_EVENT, doThis); 

        //This references doThis declared in Super
        //It cannot see doThis declared in Sub because it is both private
        //so it isn't overridden so even if you declare doThis in Sub it 
        //is completely different function
    }
    private function doThis(e:*):void{}
}

public class Sub extends Super{
    public function Super(){ //THIS IS CONSTRUCTOR OF SUB
        //There is this funky thing about flash constructors.
        //Event if you DON'T declare super() it will call it
        //without your knowledge. You can't avoid this really,
        //the only you could try is if (false) super() but I am not
        //sure this will work.
        
        //So, going further, Super's constructor is also called because
        //Sub extends this class. So by adding this event listener here
        //you end up with two listeners for the same event, like:
        //When SOME_EVENT happens call:
        //    doThis declared in Super,
        //    doThis declared in Sub

        addEventListener(SOME_EVENT, doThis)
    }
    private function doThis(e:*):void{}
}

Таким образом, вы можете попробовать отменить автоматический вызов Super с помощью if (false) super() или, что более сложно, if (Math.random() > 100) super(), но вполне вероятно, что это не сработает.

Если вы все еще не понимаете, в чем проблема, прочтите: //help.adobe.com/en_US/ActionScript/3.0_ProgrammingAS3/WS5b3ccc516d4fbf351e63e3d118a9b90204-7fcd.html и http://www.emanueleferonato.com/2009/08/26/undserstanding-as3access-modifiers-public-internal-protected-private/

person Maurycy    schedule 17.12.2010
comment
Дело в том, что если в каждом классе есть два метода с одинаковым именем, и вы вызываете его ТОЛЬКО на экземпляре SubSimba, он также вызывает версию отца! - person Lotus; 17.12.2010
comment
Автоматически вызываются только конструкторы super. Если он у вас в обычном режиме, вам нужно вызвать super () вручную, чтобы «активировать» родительские функции. - person Maurycy; 17.12.2010
comment
Maurycy, два класса имеют два метода doThis: в каждый конструктор я помещаю addEventListener (MouseEvent.MOUSE_DOWN, doThis). Теперь, когда я инсталлирую subSimba, а затем щелкаю клип, он запускает подкласс doThis и версию суперкласса. Может быть, он считает их двумя разными видеоклипами, так что один затмевает родителя или около того, я не знаю ... - person Lotus; 17.12.2010
comment
Мориси, проблема именно в этом: он должен вызывать версию подкласса, но вызывает обе! - person Lotus; 17.12.2010
comment
Может быть, происходит следующее: щелчок мышью может быть только один. Но когда вы создаете экземпляр подкласса, он автоматически вызывает конструктор суперкласса. Это означает, что щелчок инициализируется два раза, поэтому он срабатывает два раза, когда вы щелкаете. - person Lotus; 17.12.2010
comment
Да, я говорил вам с самого начала, что конструктор суперкласса вызывается автоматически. Во всяком случае обновленный ответ. - person Maurycy; 17.12.2010
comment
Спасибо. Что мне не очень нравится, так это то, что AS автоматически вызывает конструктор суперкласса ... - person Lotus; 17.12.2010