Март 2011

Руководство по 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 ( ) в зависимости от состояния соединения.

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

Далее, в подразд. «Пример: реализация режимов работы программы» разд. «Практические примеры использования пространств имен», мы вернемся к концепции использования пространств имен в качестве режимов работы программы на примере японско-английского словаря, в котором происходит переключение между различными режимами поиска.

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

namespace fruit;

var currentltemType:Namespace = fruit;

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

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

Namespace was not found or is not a compile-time constant.

По-русски это будет звучать так: Пространство имен не найдено, или оно не является константой на этапе компиляции.

Аналогичным образом переменные не могут быть использованы для указания пространства имен в директиве use namespace. Мы познакомимся с этой директивой далее, в разд. «Открытые пространства имен и директива use namespace».

Пространства имен в качестве аргументов и возвращаемых значений методов

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

public function doSomething (n:Namespace):void { trace(n);

}

Этот код передает пространство имен fruit в метод doSomething ( ): doSomething(fruit):

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

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

Этот код определяет метод getNamespace ( ), который возвращает пространство имен fruit:

public function getNamespace ( ):Namespace { return fruit:

}

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

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

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

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

Бегло просмотрите код в листинге 17.3, чтобы получить общее представление о программе. В данном примере пространства имен используются только в классах I terns и Kids Game, поэтому вы должны сосредоточить свое внимание на этих классах. Информацию о методиках, применяемых для создания пользовательского интерфейса в этом примере, можно найти в части П. Подробный анализ кода представлен сразу после листинга.

Листинг 17.3. Детская игра: пример использования значения пространства имен

// Файл fruit. as package {

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

}

// Файл color. as package {

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

}

// Файл Items. as package {

‘ // Простой класс для хранения данных, содержащий объекты Item для игры, public class Items { // Фрукты

fruit var orange:Item = new Item(«Orange», «fruit-orange. jpg», 1); fruit var apple:Item = new ItemC’Apple», «fruit-apple. jpg», 2);

// Цвета

color-var orange-.Item = new Item( «Orange», «color-orange. jpg», 3); color var purple:Item = new ItemCPurple», «color-purple. jpg», 4);

// Массивы, хранящие полные наборы элементов (то есть все фрукты // или все цвета)

fruit var itemSet:Array = [fruit::orange, fruit::apple]; color var itemSet:Array = [color::orange, color::purple];

// Массив пространств имен, представляющих

// типы наборов элементов в игре

private var itemTypes:Array = [color, fruit];

// Возвращает все элементы-фрукты, используемые в игре fruit function getltems ( ):Array { return fruit::itemSet. slice(0);

}

// Возвращает все элементы-цвета, используемые в игре color function getltems ( ):Array {

return color::itemSet. siice(O);

}

// Возвращает список доступных типов элементов, используемых в игре public function getltemTypes ( ):Аггау { return i temTypes. s1i се(0);

}

}

// Файл KidsGame. as package {

import flash. display.*;

import flash. events.*;

import flash. utils.*;

// Основной класс приложения для детской игры «Учусь читать», которое // демонстрирует основы использования пространств имен в языке ActionScript. // Игроку показывается картинка с цветом или фруктом и предлагается выбрать // название этого цвета или фрукта из списка вариантов, public class KidsGame extends Sprite { private var gameltems:Items; // Список всех элементов, используемых

// в игре

private var thisQuestionltem:Item; // Элемент для каждого вопроса private var questionScreen:QuestionScreen; // Пользовательский интерфейс

// Конструктор

public function KidsGame( ) { // Получаем элементы, используемые в игре (фрукты и цвета, // названия которых должен указать игрок) gameltems = new Items( ); // Отображаем первый вопрос newQuestion( );

}

// Создаем и отображаем новый случайный вопрос public function newQuestion ( ):void {

// Получаем полный список типов элементов (массив пространств имен)

var itemTypes:Array = gameltems. getItemTypes( );

// Случайным образом выбираем тип элемента (одно из пространств имен,

// на которые ссылается переменная itemTypes)

var randomltemType:Namespace = itemTypes[Math. floor(

Math. random( )*itemTypes.1ength)];

// Получаем элементы набора, выбранного случайным образом var items:Array = gameltems. randomltemType: -.getItems( );

// Случайным образом выбираем элемент для данного вопроса // из набора элементов

thisQuestionltem = iterns[Math. floor(Math. random( )*iterns. length)];

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

Глава 17. Пространства имен

// Удаляем предыдущий вопрос, если он существует if (questionScreen!= null) { removeChild(questionScreen);

}

// Отображаем новый вопрос

questionScreen = new QuestionScreen(this, items, thisQuestionltem); addChild(questionScreen);

}

// Обрабатываем ответ игрока public function submitGuess (guess:int) .-void { traceCGuess: » + guess + «, Correct: » + thisQuestionltem. id); if (guess == thisQuestionltem. id) { questi onScreen. di splayResult(«Correct!»); // Отключить кнопки ответа до тех пор, пока игрок не дождется // следующего вопроса. questionScreen. disable( );

// Подождать 3 секунды перед отображением следующего вопроса, var timer:Timer = new Timer(3000, 1); timer. addEventLi stener(TimerEvent. TIMER, doneResultDelay); timer. start( ); } else {

questionScreen. di spl ayResultC Incorrect. Please try again.»);

}

}

// Создает новый вопрос после того, как был получен // ответ на предыдущий.

private function doneResultDelay (e:TimerEvent):void {

newQuestion( ); } ‘

}

// Файл Item. as package {

// Простой контейнер данных, который хранит информацию об элементе, public class Item {

// Название элемента (например, «apple»)

public var name:String;

// Адрес URL, с которого загружается изображение, // представляющее элемент public var src:String;

// Уникальный идентификатор элемента, который используется // для обработки ответов игрока public var id:int;

// Конструктор

public function Item (name:String, src:String, id:int) { this. name = name;

this. src = src; this, id = id;

}

}

}

// Файл QuestionScreen. as package {

import flash. events.*;

import flash. display.*;

import flash. text.*;

import flash. net.*;

// Создает пользовательский интерфейс для вопроса public class QuestionScreen extends Sprite {

private var status:TextField;

private var game:KidsGame;

private var items:Array;

private var thisQuestionltem:Item;

// Конструктор

public function QuestionScreen (game:KidsGame,

items:Array.

Продолжение:

1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,

41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,

77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,

109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,

135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153



Полезные ссылки
Случайные записи
  • 18.08.2012">Apple назвала условия урегулирования министерства юстиции несправедливыми
  • 23.01.2011">Руководство по actionscript. часть 1, стр. 076
  • 06.03.2011">Руководство по actionscript. часть 4, стр. 147
  • 08.12.2012">Что посмотреть после работы?
  • 23.01.2011">Руководство по actionscript. часть 1, стр. 031
  • 18.05.2010">Самоучитель по креативному веб-дизайну. Книга 2, стр.49
  • 03.06.2010">Самоучитель по креативному веб-дизайну. Книга 3, стр.58
  • 06.03.2011">Руководство по actionscript. часть 4, стр. 144
  • 22.01.2011">Руководство по actionscript. часть 1, стр. 138
  • 26.02.2011">Руководство по actionscript. часть 6, стр. 063
  • 09.08.2011">Будущее — за интернетом
  • 24.02.2011">Руководство по actionscript. часть 7, стр. 008
  • 13.03.2011">Руководство по actionscript. часть 3, стр. 091
  • 23.01.2011">Руководство по actionscript. часть 1, стр. 086
  • 20.03.2011">Руководство по actionscript. часть 2, стр. 070
Опрос

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

View Results

Loading ... Loading ...