Статьи

Совет: как отладить ошибку AS3 # 1203

В этом кратком совете мы обсудим сбивающую с толку ошибку AS3 1203 «конструктор не найден», которая возникает без провокации и, к сожалению, сформулирована, к сожалению. Мы рассмотрим сценарий, в котором он появится, и как это исправить.


Во-первых, вот язык ошибки:

1
1203: No default constructor found in base class flash.display:BitmapData.

Трудно разбить это на простой английский. Итак, давайте теперь перейдем к сценарию, который вызывает эту ошибку.


Вы можете найти этот проект в загрузочном пакете, в папке » busted «. Он состоит из следующего (который можно использовать для повторного создания этого проекта, если вы предпочитаете практический подход):

  1. FLA с именем Busted.fla . Он пуст, но связан с классом документа, описанным ниже.
  2. Класс документа с именем Busted.as . Это расширяет Sprite и просто создает экземпляр класса, описанного далее, и добавляет его на сцену.
    Содержание класса следующее:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    package {
        import flash.display.*;
        public class Busted extends Sprite {
            public function Busted() {
                var bmp:Bitmap = new Bitmap(new BustedBitmap());
                addChild(bmp);
            }
        }
    }

    Класс BustedBitmap расширяет BitmapData , поэтому мы используем его для подачи объекта Bitmap , который затем добавляется на сцену.

  3. Другой файл класса с именем BustedBitmap.as . Как упоминалось ранее, это расширяет BitmapData , и его цель — быть BitmapData которая автоматически снабжает себя некоторым шумом Перлина. Его содержимое:

    1
    2
    3
    4
    5
    6
    7
    8
    package {
        import flash.display.*;
        public class BustedBitmap extends BitmapData {
            public function BustedBitmap() {
                perlinNoise(100, 100, 2, 1024, false, false, 7, true);
            }
        }
    }

    Итак, в конструкторе BustedBitmap мы вызываем perlinNoise() и, таким образом, у нас автоматически появляется что-то интересное в пиксельных данных, поэтому мы можем сразу увидеть что-то при отображении на сцене.

А теперь иди и проверь фильм. Вы получите ошибку 1203, указанную в строке 4 BustedBitmap.as . И строка 4 это …

1
public function BustedBitmap() {

Итак, что случилось? Важно помнить, что мы пишем класс, который является подклассом другого класса (в данном случае BitmapData ). Также имейте в виду, что когда создается экземпляр класса, конструктор вызывается как часть « new » процесса.

Если вы на самом деле не пишете конструктор, ActionScript будет подразумевать его для вас. Это будет выглядеть так:

1
2
3
public function [NameOfClass]() {
 
}

Где « [NameOfClass] » будет соответствовать имени вашего класса.

Точно так же, если вы пишете подкласс и не вызываете в нем super() , то ActionScript также будет подразумевать этот вызов для вас. Это будет выглядеть так:

1
2
3
4
public function [NameOfSubclass]() {
    super();
    // Other explicit code in subclass constructor
}

Обратите внимание, что это происходит в первой строке, и это просто вызов super без аргументов.

Наконец, мы добрались до корня проблемы. Если ваш подкласс пропускает явный вызов super , и конструктор вашего суперкласса имеет обязательные параметры, то ваш неявный вызов super не предоставляет требуемые параметры. Вы могли бы подумать, что ошибка несоответствия аргумента могла бы это уловить, но учтите, что, поскольку на самом деле не написано никакого кода для несоответствия, ActionScript может только пожаловаться на отсутствие конструктора по умолчанию.

В нашем примере BustedBitmap расширяет BitmapData , конструктор которого определен в документации следующим образом:

1
BitmapData(width:int, height:int, transparent:Boolean = true, fillColor:uint = 0xFFFFFFFF)

Первые два параметра обязательны, и мы их не предоставляем.


Решение, как только вы поймете проблему, предельно просто. Вам необходимо явно вызвать супер-конструктор, по крайней мере, если есть обязательные параметры. Другими словами, в нашем классе BustedBitmap эта следующая выделенная строка решит проблему:

1
2
3
4
5
6
7
8
9
package {
    import flash.display.*;
    public class BustedBitmap extends BitmapData {
        public function BustedBitmap() {
            super(600, 400);
            perlinNoise(100, 100, 2, 1024, false, false, 7, true);
        }
    }
}

И это сделает это.

В качестве обучающего момента я хотел бы добавить, что при расширении другого класса, как правило, стоит включить явный вызов super . Даже если нет никаких параметров, обязательных или иных (как в Sprite или MovieClip ), явный вызов может объявить намерение и осведомленность о природе подкласса. С практической точки зрения явные вызовы дают вам возможность выполнить некоторый код до вызова super , что может быть полезно в определенных ситуациях.


Еще одна ошибка демистифицирована; Проблема в том, что настоящая причина ошибки вполне похоронена. Как только вы станете удобнее с лопатой, исправить это достаточно просто.

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