Диагностика, ремонт и защита


Конструктор


Термин конструктор означает "нечто, что создаёт (конструирует) объекты". Мы знаем, что все объекты создаются из классов. Так что конструктор должен быть ЕОВСД (Ещё-Одним-Выдуманным-Словом-Для) класса. Ну, как бы это сказать... Точно так же, как и класс является частным случаем функции (только в ActionScript!), конструктор - это некая часть класса. Эта часть помогает "конструировать" объекты, как вы, наверное, уже догадались. Мы знаем, что объекты создаются при помощи объекта активации и аргументов. Но, стало быть и конструктор - это такой же объект активации. Да, так и есть. Трудности начнутся, когда мы вспомним, что объекта активации не существует, пока мы его не вызовем, а по окончании своей миссии он уничтожается - таких друзей в адресную книгу не вносят. Получается, что единственный способ "активировать" этот объект активации - вызвать свойство, которому он назначен, то есть объект, который даёт имя классу. Это прекрасно работает, потому что аргументы как бы "зажаты" между этими двумя объектами и так прочно друг к другу привязаны, что их часто рассматривают, как единое целое.

Почему нам так важно дать наиболее полное и точное определение конструктора и его работы? Потому что это ещё одно из недокументированных ключевых слов ActionScript, которые иногда бывают просто необходимы. Всякий экземпляр имеет свойство constructor и оно указывает на класс, который его создал, точнее на объект, давший имя классу. Когда вы рассуждаете о конструкторе с точки зрения экземпляра (как в случае с конструктором rover'а), то конструктор это класс, который создал экземпляр. Когда речь идёт о частях класса, то конструктор это скорее объект активации, наряду с аргументами и объектом имени. На самом же деле, подразумевается прототип или свойства, назначенные объекту имени класса (например, Dog.count), потому что они напрямую не участвуют в "конструировании" объекта. Кое-кто может сказать, что мы просто играем словами. Да, возможно, это так. В большинстве других объектно-ориентированных языках программирования конструктор и имя класса, это абсолютно разные понятия. В ActionScript они, конечно, тоже не взаимозаменяемы, но довольно тесно связаны друг с другом и разница между ними подчас очень невелика. Вот почему так важно оперировать точными определениями этих понятий. Фигурально выражаясь, можно сказать, что:

  • Class - это нечто вроде хижины.
  • Constructor - это её часть, отвечающая за создание новых вещей.

Ранее мы задавались вопросом, каким именно образом экземпляры ссылаются на класс, который их создал. Ответ на этот вопрос - ключевое слово constructor. Он всегда используется изнутри объекта. Наилучшим образом он действует в границах экземпляра, который вы создали из вашего класса (хотя этим его действие, конечно же, не ограничивается, всегда полезно "пощупать" ActionScript в поисках чего-то новенького и неописанного!). Вот два способа, нахождения конструктора из экземпляра. Dog = function( ) { this.instNum = ++this.constructor.count; } // следующие два свойства на самом деле не являются частью 'конструктора' Dog.count = 0; // используется для подсчета созданных собак Dog.className = "Dog"; // используется для запоминания имени класса rover = new Dog( ); fido = new Dog( ); trace( rover.instNum ); // 1 (первая собака создана) trace( fido.instNum ); // 2 (вторая собака создана) trace( rover.constructor.className ); // Dog

Хотя использование конструктора не всегда нормативно, иногда без него просто не обойтись. Очевидным преимуществом доступа к свойствам Dog через instance.constructor.xxx вместо Dog.xxx является то, что если вы когда-нибудь измените имя класса Dog на Canine, вам не придётся перелопачивать весь ваш код в поисках кусков, где есть ссылка на Dog. Такой способ также делает ваш код намного более портативным на тот случай, если, например, вам захочется использовать его в другом классе или даже в другой программе.

Что интересно, у прототипа класса всё-таки есть конструктор, потому что это, в конце концов, такой же объект, как и любой другой - объект, который был кем-то создан. Когда вы определяете класс, он немедленно создаёт объект имени, но не создаёт объекта активации (который создаётся только когда его вызывают). Но вот объект прототипа всё-таки создаётся и это происходит, как только мы определяем класс. Куда указывает конструктор прототипа? Точно так же, как и экземпляр, он указывает на объект класса имени. Но как бы нам это проверить? Можно просто добавить в верхнюю функцию следующее выражение: trace( Dog.prototype.constructor.className ); // Dog

Довольно громоздко, не так ли? Но если присмотреться, мы увидим, что эта строка всего лишь говорит: "Отследить имя класса объекта, создавшего ("сконструировавшего") прототип Dog". Ладно, если это до сих пор не вполне понятно, то попробуем по-другому. Если перемещать эту строку вверх и вниз по коду, то мы увидим, что объект прототипа создается, как только мы определяем класс Dog, до того, как в прототипе устанавливаются какие-либо свойства.

И напоследок ещё немного странностей. Объект имени класса (Dog) не имеет свойства конструктора, даже не смотря на то, что это объект, который был создан. Имена функций также не имеют конструктора в ActionScript, даже не смотря на то что в других подобных языках программирования (например, в JavaScript) это не так. Причины объяснить не так просто. Попробуйте для начала перелопатить весь ActionScript так, чтобы ему было "удобно" в "крошечном" 200-килобайтном Flash Playr'е. Вот-вот, и я про то же! Давайте-ка лучше перейдём к следующему разделу про методы. Он интересный!

<<    ООП во Flash 5    >>

 









Начало  Назад  Вперед


Книжный магазин