Руководство по actionscript. часть 2, стр. 147

На русском языке она будет звучать так: Обращение к несуществующему свойству orange.

Компилятор не может найти переменную или метод (то есть «свойство») по имени orange, поскольку в области видимости метода-конструктора Items не существует переменной или метода с простым идентификатором orange. Переменные fruit: : orange и color: : orange уточняются с помощью пространств имен, поэтому они оказываются недоступны при попытке обратиться к ним с применением неуточненного идентификатора. И все-таки далее, в разд. «Открытые пространства имен и директива use namespace», мы познакомимся с упрощенным способом обращения к уточненным идентификаторам без использования уточняющего пространства имен.

Очевидно, что в листинге 17.1 не показана полнофункциональная игра, но этот код призван дать вам представление о базовом синтаксисе и использовании пространств имен. Мы завершим создание нашей игры далее в этой главе.

На этом начальном этапе разработки нашей игры вы могли бы поинтересоваться, почему вместо использования пространств имен мы не можем просто определить переменные с длинными именами, например orangeFruit и orangeColor. Или почему нельзя разделить оба вида oranges, присвоив их двум отдельным массивам, как показано в следующем коде:

var fruitList:Array = ["orange", "apple", "banana"]; var colorList:Array = ["orange", "red", "blue"];

Описанные варианты имеют право на жизнь. Фактически, учитывая выбранный уровень упрощений, нам действительно было бы лучше использовать массивы или более длинные имена переменных. Но не стоит пока терять веру в пространства имен; мы собираемся строить системы с более сложными сценариями использования.

Доступность пространств имен

Как и в случае с определениями переменных и методов, определения пространств имен могут быть изменены с помощью модификаторов управления доступом publ i с, internal, protected и private. Местоположение определения пространства имен в сочетании с модификатором управления доступом этого определения указывают, где может быть использован результирующий идентификатор пространства имен.

Вот несколько основных правил, которые помогут решить, где разместить ваши пространства имен.

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

? Если вам требуется пространство имен, которое задает видимость переменных и методов внутри одного класса, определяйте его на уровне класса.

? Если пространство имен будет применяться лишь иногда внутри функции и вы знаете идентификатор URI этого пространства имен, но не можете обращаться к нему напрямую, определяйте пространство имен на уровне функции.

Рассмотрим несколько примеров, начав с пространств имен, задаваемых на уровне пакета.

Руководство по actionscript. часть 2, стр. 148

Доступность определений пространств имен на уровне пакета

В следующем коде мы определяем идентификатор пространства имен fruit в пакете kidsgame:

package kidsgame { public namespace fruit = «http://www. example. com/games/kidsgame/fruit»:

}

Поскольку идентификатор fruit объявлен на уровне пакета с использованием модификатора управления доступом publ iс, он может быть применен для уточнения любой переменной или метода в данной программе. Безусловно, код за пределами пакета kidsgame должен импортировать пространство имен fruit перед его использованием, как показано в следующем примере:

package anyPackage { // Импортируем пространство имен fruit import kidsgame. fruit;

public class AnyClass { // Здесь можно применять пространство имен fruit, поскольку оно уже // было импортировано

fruit var banana:String = «Long yellow fruit»;

}

}

Теперь сделаем так, чтобы доступность пространства имен color была ограничена одним пакетом, используя модификатор управления доступом internal:

package kidsgame {

internal namespace color = «http://www. example. com/games/kidsgame/color»;

}

Когда идентификатор пространства имен определяется с применением модификатора управления доступом internal на уровне пакета, он может быть использован только внутри пакета, в котором определен. Это демонстрирует следующий код.

Руководство по actionscript. часть 2, стр. 149

Package kidsgame { public class Items { // Здесь можно применять пространство имен color. Использование // пространства имен color допустимо, поскольку оно происходит внутри // пакета kidsgame

color var green:String = «Color obtained by mixing blue and yellow»;

}

}

package cardgame { import kidsgame. col or; public class CardGame { // Недопустимо.

// Пространство имен color может быть использовано // только внутри пакета kidsgame.

color var purple:String = «Color obtained by mixing blue and red»;

}

}

При определении пространств имен на уровне пакета могут применяться модификаторы управления доступом public и internal, при этом использование модификаторов управления доступом private и protected не допускается. Более того, если в определении пространства имен на уровне пакета модификатор управления доступом опускается, применяется модификатор управления доступом internal. Например, следующий код:

package kidsgame { // internal указывается явно internal namespace fruit;

}

аналогичен данному коду:

package kidsgame { // internal подразумевается неявно namespace fruit;

}

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

Руководство по actionscript. часть 2, стр. 150

Доступность определений пространств имен на уровне класса

Идентификатор пространства имен, определенный в классе с использованием модификатора управления доступом private, доступен только внутри данного класса и недоступен в его подклассах и в любом другом внешнем коде:

public class А { private namespace n = «http://www. example. eom/n»; // Отлично. Идентификатор пространства имен п доступен в этом месте, n var someVariable:int;

}

public class В extends A { // Ошибка. Идентификатор пространства имен п недоступен в этом месте, n var someOtherVariable:int;

}

Мы можем использовать пространство имен, объявленное с применением модификатора управления доступом private, для реализации системы управления доступом на основании разрешений. Эта система рассматривается далее, в подразд. «Пример: управление доступом на основании разрешений» разд. «Практические примеры использования пространств имен».

Идентификатор пространства имен, объявленный в классе с использованием модификатора управления доступом protected, internal или public, доступен напрямую в любом месте данного класса и его подклассов, но недоступен в любом другом внешнем коде. Такое определение пространства имен является противоположностью определения на уровне пакета с применением модификатора управления доступом pub lie, создающего идентификатор пространства имен, к которому можно обращаться напрямую из любого места программы. Это демонстрирует следующий код:

public class А { public namespace n = «http://www. example. eom/n»;

// Отлично. Идентификатор пространства имен п доступен напрямую

// в этом месте.

n var someVariable:int;

}

public class В extends A { // Отлично. Идентификатор пространства имен п доступен напрямую // в этом месте, n var someOtherVariable:int;

}

public class С {

// Ошибка. Идентификатор пространства имен п напрямую не доступен // в этом месте.

Руководство по actionscript. часть 2, стр. 151

// (Но идентификатор п мог бы быть доступен, если бы он был определен

// на уровне пакета.)

n var yetAnotherVariable:int;

}

Стоит отметить, что, хотя идентификатор пространства имен, объявленный в классе с использованием модификатора управления доступом internal или public, доступен напрямую только в этом классе и его подклассах, к объекту Namespace, на который ссылается идентификатор пространства имен, можно обратиться с применением синтаксиса обращения к статическим переменным.

Например, чтобы обратиться к объекту Namespace, на который ссылается идентификатор пространства имен п в предыдущем коде, мы могли бы использовать выражение: А. п. Доступ к объектам Namespace с помощью синтаксиса обращения к статическим переменным регламентируется обычными ограничениями, налагаемыми на статические переменные, объявленные с применением модификаторов управления доступом protected, internal и public. В предыдущем коде, поскольку идентификатор п объявлен с использованием модификатора управления доступом public, выражение А. п является допустимым в любом коде, который имеет доступ к классу А. Если бы идентификатор п был объявлен с использованием’ модификатора управления доступом internal, выражение А. п было бы допустимым только внутри пакета, содержащего определение данного пространства имен. Если бы идентификатор п был объявлен с использованием модификатора управления доступом protected, выражение А. п было бы допустимым только внутри класса А и его подклассов.

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

А. п var p:int; // Недопустимо. А. п не является константой // на этапе компиляции.

Итак, если мы не можем использовать выражение А. п для уточнения определений, для чего оно может использоваться вообще? Оставайтесь с нами, мы скоро узнаем ответ на этот вопрос в разд. «Присваивание и передача значений пространств имен».

Пока рассмотрим последнюю тему, связанную с доступностью пространств имен: определение пространств имен в методах и функциях.

Доступность определений пространств имен на уровне функции

Как и в случае с другими определениями на уровне функции, идентификатор пространства имен, объявленный на уровне функции, не может включать никакие модификаторы управления доступом (то есть он не может быть объявлен с использованием модификаторов управления доступом public, private и т. д.) и доступен только в области видимости данной функции:

public function doSomething ( ):void { // Это недопустимо

private namespace n = «http://www. example. eom/n»;

}

Более тогог определения локальных переменных и вложенных функций не могут использовать пространства имен в качестве атрибутов:

public function doSomething ( ):void { // Это тоже недопустимо namespace n = «http://www. example. eom/n»; n var someLocalVariable:int = 10;

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

Руководство по actionscript. часть 2, стр. 152

Public function doSomething ( ):void { // Это допустимо

namespace n = «http://www. example. eom/n»; trace(n: .-someVariable) ;

}

Определения пространств имен на уровне функции используются только в редких случаях, когда функция не может обратиться к пространству имен, которое временно требуется для этой функции, напрямую, при этом идентификатор URI пространства имен известен. Например, функция, которая обрабатывает фрагмент XML-документа, содержащего уточненные имена элементов, может использовать код, похожий на следующий:

public function getPrice ( ):void { namespace htmlNS = «http://www. w3.org/1999/xhtml»; output. text = htmlNS::table. htmlNS::tr[l].htmlNS::td[l].price;

}

Пространства имен XML будут рассматриваться в гл. 18.

Видимость уточненных идентификаторов

Наверняка вы заметили, что в этой книге определения уточненных идентификаторов не включают модификаторы управления доступом (public, internal, protected или private). Мы видели достаточно много таких определений:

fruit var orange:String = «Round citrus fruit»:

Однако ни одного такого (обратите внимание на присутствие модификатора управления доступом private):

private fruit var orange:String = «Round citrus fruit»;

По понятной причине нельзя использовать модификаторы управления доступом в определениях, которые включают уточняющее пространство имен. Например, следующий код:

private, fruit var orange:String;

вызовет ошибку:

Access specifiers not allowed with namespace attributes

На русском языке она будет звучать так: Использование спецификаторов вместе с атрибутами пространства имен недопустимо.

Руководство по actionscript. часть 2, стр. 153

Однако если нельзя использовать модификаторы управления доступом, с помощью чего можно управлять доступностью уточненного идентификатора? Ответ: с помощью доступности идентификатора уточняющего пространства имен.

Видимость уточненных идентификаторов

373

^ I Доступность уточняющего пространства имен в уточненном идентификаторе определя-

Ач ет доступность этого идентификатора. Если уточняющее пространство имен доступно в указанной области видимости, значит, доступен и уточненный идентификатор.

Например, в выражении game items. fruit: : orange переменная fruit: : orange доступна тогда, и только тогда, когда пространство имен fruit доступно в области видимости этого выражения. Доступность переменной fruit: : orange целиком и полностью определяется доступностью пространства имен fruit.

В листинге 17.2 демонстрируется видимость уточненного идентификатора на примере обобщенного кода.

Листинг 17.2. Демонстрация видимости уточненного идентификатора

// Создаем пространство имен п в пакете one. видимое только в этом пакете package one { internal namespace n = «http://www. example. eom/n»;

// Создаем переменную n::p в классе А, пакет one package one { public class A { n var p:int = 1:

// Поскольку пространство имен n объявлено с использованием модификатора // управления доступом internal, переменная п::р доступна в любом месте // внутри пакета one package one { public class В { public function В ( ) { var a:A = new A( ); trace(a. n::p); // OK

// Однако переменная n::p недоступна для кода за пределами пакета one package two { import one.*;

public class С { public function С ( ) { var a:A = new A( );

trace(a. n::p); // Недопустимо, поскольку пространство имен n

// объявлено с использованием модификатора управления // доступом internal в пакете one. и поэтому // недоступно в пакете two

Сравнение уточненных идентификаторов

Два пространства имен считаются одинаковыми тогда, и только тогда, когда совпадают их названия (URI). Например, чтобы определить, являются ли одинаковыми пространства имен в уточненных идентификаторах fruit : : orange и color: : orange, среда выполнения Flash не проверяет, соответствуют ли буквы слова «fruit» первого идентификатора буквам слова color второго идентификатора. Вместо этого среда Flash проверяет, совпадают ли значения переменной ur i экземпляра класса Namespace, на который ссылается идентификатор fruit, и экземпляра класса Namespace, на который ссылается идентификатор color. Если значение переменной f ruit. uri равняется значению переменной color, uri, то пространства имен считаются одинаковыми.

Руководство по actionscript. часть 2, стр. 154

Таким образом, когда мы записываем следующее выражение:

trace(fruit::orange == color::orange);

среда Flash выполняет данное сравнение (обратите внимание на использование расширенных имен, которые рассматривались в разд. «Уточненные идентификаторы»):

{http://www. examplе. com/games/ki dsgame/fruit}orange == {http://www. example. com/games/ki dsgame/col or}orange

Даже если два уточненных идентификатора внешне кажутся различными, на деле они могут оказаться одинаковыми и привести к неожиданным конфликтам имен. Например, в следующем коде попытка определить переменную ns2 : : р вызовет ошибку на этапе компиляции, поскольку переменная с расширенным именем {http : / /www. example. com/general}p уже существует:

namespace nsl = «http://www. example. com/general»

namespace ns2 = «http://www. example. com/general»

nsl var p:int = 1:

ns2 var print = 2; // Ошибка! Повторное определение переменной!

Даже несмотря на то, что идентификаторы ns 1 и ns 2 являются различными, переменные nsl: :р и ns2: : р считаются одинаковыми, поскольку они имеют одинаковые расширенные имена ({http: / /www. example. com/general }p).

Стоит отметить, что названия пространств имен (идентификаторы URI) сравниваются как строки, с учетом регистра символов. Поэтому, несмотря на то, что для браузера два идентификатора URI, которые отличаются только регистром символов, будут считаться одинаковыми, в языке ActionScript они будут считаться различными. В ActionScript следующие два идентификатора URI считаются различными, поскольку слово example в первом случае начинается со строчной буквы, а во втором — с прописной:

namespace nsl = «http://www. example. com» namespace ns2 = «http://www. Example. com» trace(nsl == ns2); // Отображает: false

Присваивание и передача значений пространств имен

Поскольку каждое пространство представлено экземпляром класса Namespace, пространства имен могут присваиваться переменным или элементам массива, передаваться в методы и возвращаться из методов и вообще могут быть использованы, как любой другой объект. Эта гибкость позволяет:

? передавать пространство имен из одной области видимости в другую;

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

Руководство по actionscript. часть 2, стр. 155

При использовании пространств имен в ActionScript эти действия являются крайне важными. Узнаем почему.

Присваивание значения пространства имен переменной

Чтобы присвоить значение пространства имен переменной, мы используем точно такой же синтаксис присваивания, как и для любого другого значения. Например, следующий код присваивает значение пространства имен fruit переменной currentltemType (напомним, что значение пространства имен — это объект класса Namespace):

// Файл fruit. as package {

namespace fruit = «http://www. example. com/games/kidsgame/fruit»;

}

// Файл Items. as package { public class Items {

// Присваиваем значение пространства имен fruit переменной

// currentltemType

private var currentltemType-.Namespace = fruit;

}

}

Переменная, которая ссылается на объект класса Namespace, может быть использована для формирования уточненного идентификатора. Например, рассмотрим следующее определение переменной:

fruit var orange:String = «Round citrus fruit»;

Для того чтобы обратиться к этой переменной, мы можем использовать выражение fruit: : orange либо currentltemType: : orange. Присвоив переменной currentltemType некоторое другое пространство имен, можно динамически изменить смысл идентификатора currentltemType: -.orange, а также всех остальных методов и переменных, уточняемых переменной currentltemType по всей программе. Если организовать группы методов и переменных с помощью пространств имен, мы можем воспользоваться возможностью динамического

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

Руководство по actionscript. часть 2, стр. 156

Например, предположим, что мы создаем приложение для мгновенного обмена сообщениями, которое может функционировать в двух режимах, представляемых соответствующими пространствами имен offline и online. В приложении определены две версии метода с именем sendMes sage ( ): одна версия предназначена для работы в режиме онлайн, а другая — для работы в автономном режиме.

online sendMessage (msg.-String):void { // Отправить сообщение прямо сейчас…

}

offline sendMessage (msg.-String):void { // Поставить сообщение в очередь и отправить его позднее…

}

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

private function connectListener (e:Event):void { currentMode = online;

}

private function closeListener (e:Event):void { currentMode = offline;

}

Во всех обращениях к методу sendMessage ( ) в качестве уточняющего пространства имен применяется переменная currentMode, как показано в следующем коде:

currentMode::sendMessage(«yo dude»);

Изменяя значение переменной currentMode, приложение динамически переключается между двумя версиями метода sendMessage ( ) в зависимости от состояния соединения.



Полезные ссылки
Случайные записи
  • 04.03.2011">Руководство по actionscript. часть 5, стр. 047
  • 24.02.2011">Руководство по actionscript. часть 7, стр. 002
  • 10.05.2010">Самоучитель по креативному веб-дизайну. Книга 1, стр.129
  • 22.01.2011">Руководство по actionscript. часть 1, стр. 126
  • 23.01.2011">Руководство по actionscript. часть 1, стр. 048
  • 12.03.2011">Руководство по actionscript. часть 3, стр. 119
  • 02.03.2011">Руководство по actionscript. часть 5, стр. 085
  • 08.03.2011">Руководство по actionscript. часть 4, стр. 077
  • 11.05.2010">Самоучитель по креативному веб-дизайну. Книга 1, стр.24
  • 06.03.2011">Руководство по actionscript. часть 4, стр. 130
  • 12.03.2011">Руководство по actionscript. часть 3, стр. 125
  • 17.05.2010">Самоучитель по креативному веб-дизайну. Книга 2, стр.112
  • 22.03.2011">Руководство по actionscript. часть 2, стр. 026
  • 06.03.2011">Руководство по actionscript. часть 4, стр. 137
  • 30.01.2011">Форматы растровой графики
Опрос

Какие цвета вы предпочитаете?

View Results

Loading ... Loading ...