Программирование на JAVA
Меню :
Стартовая
Основы программирования
Программирование на JAVA
Программирование на C++
Программирование на Pascal
Задачи по программированию
Понятно, что хотя с точки зрения компилятора это корректная конструкция, попытка сослаться на две разные переменные через одно имя успехом не увенчается. Надо заметить, что такие ошибки случаются порой даже у опытных разработчиков.
Во-первых, рассмотрим, из-за чего возникла конфликтная ситуация. Есть два элемента языка — аргумент метода и поле класса, области видимости которых пересеклись. Область видимости поля класса больше, она охватывает все тело класса, в то время как область видимости аргумента метода включает только сам метод. В таком случае внутри области пересечения по простому имени доступен именно аргумент метода, а поле класса "затеняется" (shadowing) объявлением параметра метода.
Остается вопрос, как в такой ситуации все же обратиться к полю класса. Если доступ по простому имени невозможен, надо воспользоваться составным. Здесь удобнее всего применить специальное ключевое слово this (оно будет подробно рассматриваться в следующих главах). Слово this имеет значение ссылки на объект, внутри которого оно применяется. Если вызвать метод setAge() у объекта класса 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.