97. Пространство имен namespace

Что такое пространство имен(Namespace)? Если вкратце, это возможность ограничить доступ к классу, методу или свойству. Например атрибуты private, public, protected и internal являются встроенными пространствами имён, которые ограничивают доступ. Если кто не знает их предназначение, вот краткое описание:

  • public – метод/свойство доступно отовсюду
  • private – метод/свойство доступно только внутри класса
  • protected – метод/свойство доступно внутри класса и классам-наследникам
  • internal – метод/свойство доступно только тем классам, которые лежат в одном каталоге(пакете) с текущим классом


Рассмотрим пример, как можно использовать пространство имен. В первую очередь пространство имен необходимо создать, делается это с помощью оператора namespace:

, далее в описании функции вместо стандартных операторов доступа (public, private …) указываем имя нашего созданного пространства имен:

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


Готовый класс с пространством имен debug, можете посмотреть в этом примере:

Если вы попытаетесь вызвать функцию run без debug:: вы получите ошибку:


Вы можете написать несколько функций run, которые будут лежать в разных пространствах имен:

При выполнении этого кода, в окне консоли мы увидим:

run debug
run release
run private
run private

В этом примере мы создали три функции с одинаковыми именами run, которые лежат в трех разных пространствах имен: два собственных(debug и release) и одно стандартное(private). Обратите внимание на строки 16 и 17, как видите если метод определен в стандартном пространстве имен, его тоже можно вызвать явно указав его пространство имен, при этом нет разницы как вызвать метод private::run() или run() или же this.run()


Давайте подумаем, где нам может пригодиться такая возможность… Представьте себе что вы разрабатываете AIR приложение для платформ iOS и Android. И у вас есть метод draw, который должен по разному работать в этих платформах, и который очень часто вызывается из разных мест. Каждый раз писать if else или switch case, что бы понять в какой платформе мы сейчас находимся, не очень удобно. Для этого вы можете создать два пространства имен ios/android и создать для каждого из них свой метод draw():

Обратите внимание на строки 7-8, здесь мы создаем два пространства имен ios и android. А в строке 10 создаем переменную типа Namespace, которая будет хранить ссылку на текущее пространство имен. Далее в строке 15 мы записываем в переменную currentPlatform текущее пространство имен ios, и вызываем метод draw используя не название пространства имен(ios), а переменную currentPlatform(строка 17), которая ссылается на пространство имен ios.

Вы можете так же передать ссылку на пространство имен в конструкторе класса DrawMobile. Для этого необходимо пространства имен ios и android определить как public(в строке 7 и 8):

Что бы передать в конструктор ссылку на необходимое пространство имен, воспользуйтесь конструкцией:

или так:


Неявное указание пространства имен. До сих пор, при вызове методов из собственное пространства имен, мы всегда явно указывали имя пространства имен: <пространство имен>::<функция>(). Делать это необязательно, если вы укажите какое пространство имен необходимо использовать по умолчанию в пределах видимости(что это значит расскажу чуть позже) , делается это с помощью оператора use namespace <пространство имен>. Вот как можно использовать оператор use namespace:

Выше я писал что оператор use namespace действует только в пределах видимости, это значит что в вышеуказанном примере пространство имен по умолчанию ios будет действовать только внутри конструктора класса DrawMobile. В этом легко убедиться если попробовать вызвать метод this.draw(); например в обработчике Event.ENTER_FRAME:

В строке 23 мы получим ошибку, т.к. в методе frameHandler не определено пространство имен по умолчанию. Посмотрите на следующий код:

В этом коде, один раз будет выполнен метод draw для iOS, а в обработчике frameHandler будет вызываться метод draw для Android.

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

В этом классе, задано дефолтовое пространство имен, как в конструкторе DrawMobile, так и в методе frameHandler.


Все выше сказанное относится и к свойствам класса:

В консоли мы увидим:

paltformName: iOS
draw iOS


Подведя итоги, попробую привести другой пример, где можно использовать пространства имен.

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

nameSpaceMenu1

Т.е. у нас есть корневой каталог menu, в нем лежит основной класс компонента MenuView. В каталоге menu есть подкаталог(пакет) buttons, здесь у нас могут лежать различные классы кнопки для меню, например MenuButton. У класса MenuButton есть метод run:
Класс MenuView.as:

Класс MenuButton.as:

И класс который использует это меню:


Как видите метод run класса MenuButton доступен извне компонента menu. Если же вам необходимо сделать так, что бы метод run был доступен только внутри компонента menu, т.е. всем класса которые лежат внутри пакета menu – можно воспользоваться пространством имен. В каталоге menu создаем файл с именем например menuNamespace.as, который будет выглядеть так:

В классе MenuButton, методу run задаем пространство имен menuNamespace:

Обратите внимание что файл, где описано наше пространство имен menuNamespace, необходимо импортировать в класс MenuButton(строка 5), т.к. эти файлы лежат в разных каталогах(пакетах).

Во всех классах внутри каталога(пакета) menu, которые должны иметь доступ к функции run, должны использовать пространство имен menuNamespace. Например класс MenuView будет выглядеть так:

Теперь в главном классе приложения:

, в строчке 12 мы получим ошибку, т.к. этот класс не имеет доступа к пространству имен menuNamespace. Конечно же разработчику ни чего не мешает написать

внутри этого класса. Только в этом случае разработчик сознательно идет на нарушение правил и сам отвечает за возможные ошибки. Смысл всей этой процедуры – дать понять разработчикам которые будут использовать этот компонет – что метод run не должен вызываться извне компонента menu.

Да прeбудет с вами Flash.
Serious Sam
Эту статью прочитали 1014 раз

Возникли вопросы по статье? Не стесняйтесь спрашивать в комментариях или любым другим способом на странице Контакты .

Присоединяйтесь к нам в социальных сетях: ВКонтакте , Twitter и Facebook
Понравилась статья? Буду благодарен если вы поделитесь ссылкой с друзьями:


Комментарии ВКонтакте:




Комментарии Facebook:




Комментарии WordPress: