русс | укр

Языки программирования

ПаскальСиАссемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование

Все о программировании


Linux Unix Алгоритмические языки Аналоговые и гибридные вычислительные устройства Архитектура микроконтроллеров Введение в разработку распределенных информационных систем Введение в численные методы Дискретная математика Информационное обслуживание пользователей Информация и моделирование в управлении производством Компьютерная графика Математическое и компьютерное моделирование Моделирование Нейрокомпьютеры Проектирование программ диагностики компьютерных систем и сетей Проектирование системных программ Системы счисления Теория статистики Теория оптимизации Уроки AutoCAD 3D Уроки базы данных Access Уроки Orcad Цифровые автоматы Шпаргалки по компьютеру Шпаргалки по программированию Экспертные системы Элементы теории информации

Область видимости имен


Дата добавления: 2015-06-12; просмотров: 637; Нарушение авторских прав


Областью видимости объявления некоторого элемента языка назы­вается часть программы, откуда допускается обращение к этому элементу по простому имени.

При рассмотрении каждого элемента языка будет указываться его область видимости, однако имеет смысл собрать эту информацию в од­ном месте.

Область видимости доступного пакета — вся программа, то есть лю­бой класс может использовать доступный пакет. Однако необходимо по­мнить, что обращаться к пакету можно только по его полному составно­му имени. К пакету java.lang ни из какого места нельзя обратиться как к просто lang.

Областью видимости импортированного типа являются все объявле­ния верхнего уровня в этом модуле компиляции.

Областью видимости типа (класса или интерфейса) верхнего уров­ня является пакет, в котором он объявлен. Из других пакетов доступ возможен либо по составному имени, либо с помощью импортирующе­го выражения, которое помогает компилятору воссоздать составное имя.

Область видимости элементов классов или интерфейсов — это все тело типа, в котором они объявлены. Если обращение к этим эле­ментам происходит из другого типа, необходимо воспользоваться со­ставным именем. Имя может быть составлено из простого или состав­ного имени типа, имени объектной переменной или ключевых слов super или this, после чего через точку указывается простое имя эле­мента.

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

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

intx;

for{inti=0; i<10; i++) { intt=5+i;}

// здесь переменная t уже недоступна,

// так как блок, в котором она была объявлена,



//уже завершен, а переменная х еще недоступна,

//так как пока не была инициализирована

Определенные проблемы возникают, когда происходит перекрытие областей видимости и возникает конфликт имен различных конструкций языка.

"Затеняющее" объявление (Shadowing)

Самыми распространенными случаями возникновения конфликта имен являются выражение, импортирующее пакет, и объявление локальных переменных, или параметров методов, конструкторов, обработчиков ошибок. Импорт пакета подробно рассматривался в этой главе. Если им­портированный и текущий пакеты содержат одноименные типы, то их об­ласти пересекаются. Как уже говорилось, предпочтение отдается типу из текущего пакета. Также рассказывалось о том, как эту проблему решать.

Перейдем к проблеме перекрытия имен полей класса и локальных пе­ременных. Пример:

class Human { intage; // возраст intgetAge(){ return age;}

void setAge{int age) {age=age; // ??? } }

В классе Human (человек) объявлено поле age (возраст). Удобно оп­ределить также метод setAge(), который должен устанавливать новое зна­чение возраста для человека. Вполне логично сделать у метода setAge() один входной аргумент, который также будет называть age (ведь в качест­ве этого аргумента будет передаваться новое значение возраста). Получа­ется, что в реализации метода setAge() нужно написать age=age, в первом случае подразумевая поле класса, во втором - параметр метода. По­нятно, что хотя с точки зрения компилятора это корректная конструкция,попытка сослаться на две разные переменные через одно имя успехом не увенчается. Надо заметить, что такие ошибки случаются порой даже у опытных разработчиков.

Во-первых, рассмотрим, из-за чего возникла конфликтная ситуа­ция. Есть два элемента языка — аргумент метода и поле класса, области видимости, которых пересеклись. Область видимости поля класса больше, она охватывает все тело класса, в то время как область видимости аргу­мента метода включает только сам метод. В таком случае внутри области пересечения по простому имени доступен именно аргумент метода, а по­ле класса "затеняется" (shadowing) объявлением параметра метода.

Остается вопрос, как в такой ситуации все же обратиться к полю класса. Если доступ по простому имени невозможен, надо воспользо­ваться составным. Здесь удобнее всего применить специальное ключевое слово this (оно будет подробно рассматриваться в следующих главах). Слово this имеет значение ссылки на объект, внутри которого оно при­меняется. Если вызвать методsetAgeO у объекта класса Human и ис­пользовать в этом методе слово this, то его значение будет ссылкой на данный объект.

Исправленный вариант примера:

class Human {int age;// возраст void setAge{int age) {this.age=age; // верное присвоение! } }

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

'Заслоняющее" объявление (Obscuring)

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

Приведем пример, который частично иллюстрирует такой случай:

import java.awt/;

public class Obscuring {static Point Test = new Point(3,2);

public static void main (String s[]) { print(Test.x);} } class Test {static int X = -5; }

В методе main() простое имя Testодновременно обозначает имя поля класса Obscruing и имя другого типа, находящегося в том же пакете,— Test.С помощью этого имени происходит обращение к полю х, которое определено и в классе Java.awt. Point и Test.

Результатом этого примера станет 3, то есть переменная имеет более высокий приоритет. В свою очередь, тип имеет более высокий приоритет, чем пакет. Таким образом, обращение к доступному в обычных условиях типу или пакету может оказаться невозможным, если есть объявление од­ноименной переменной или типа, имеющее более высокий приоритет. Такое объявление называется "заслоняющим" (obscuring).

Эта проблема, скорее всего не возникнет, если следовать соглашениям по именованию элементов языка Java.



<== предыдущая лекция | следующая лекция ==>
Уникальность имен пакетов | Соглашения по именованию


Карта сайта Карта сайта укр


Уроки php mysql Программирование

Онлайн система счисления Калькулятор онлайн обычный Инженерный калькулятор онлайн Замена русских букв на английские для вебмастеров Замена русских букв на английские

Аппаратное и программное обеспечение Графика и компьютерная сфера Интегрированная геоинформационная система Интернет Компьютер Комплектующие компьютера Лекции Методы и средства измерений неэлектрических величин Обслуживание компьютерных и периферийных устройств Операционные системы Параллельное программирование Проектирование электронных средств Периферийные устройства Полезные ресурсы для программистов Программы для программистов Статьи для программистов Cтруктура и организация данных


 


Не нашли то, что искали? Google вам в помощь!

 
 

© life-prog.ru При использовании материалов прямая ссылка на сайт обязательна.

Генерация страницы за: 2.423 сек.