Область видимости . Объектно-ориентированное программирование на Java. Платформа Java SE
Классы имеют двойную цель.
Они могут использоваться для определения новых типов данных, которые связаны с решением задачи.
И также они служат для структурирования кода.
У нас есть инкапсулированные переменные и методы в классах.
Однако любая другая часть программы может изменять переменные и вызывать методы.
И иногда важно скрыть доступ к некоторым переменным или методам, чтобы контролировать возникновение возможных проблем.
Представьте себе, что в нашей модели автомобиля у нас есть поле gas, которое служит индикатором оставшегося топлива в машине.
Представьте, что эта переменная должна содержать значение от 0 до 100, 0 означает пустой бак, а 100 – полный.
Теперь, когда автомобиль тратит при движении n единиц топлива, эти n единиц вычитаются из переменной gas.
Мы также можем заполнить бак на АЗС, и в этом случае переменная gas увеличивается.
Таким образом, топливо уменьшается с помощью метода перемещения и увеличивается с помощью метода заполнения.
Однако у нас может быть проблема, поскольку любая часть программы имеет доступ к этой переменной gas.
Кто-то может даже изменить переменную на отрицательное число, что не имеет смысла.
Таким образом, два метода, которые должны изменять и должны иметь доступ к этой переменной, не являются единственным контролем этой переменной, и мы должны каким-то образом ограничить этот доступ.
Давайте посмотрим на эти два модификатора доступа, public и private.
На данный момент мы будем использовать их только для переменных и методов класса.
Здесь мы пишем private до объявления переменной gas.
Это означает, что мы можем получить доступ к ней только в классе, а не вне класса.
Два метода, move и fill, определяются как public, и поэтому могут быть вызваны вне класса.
Это типичная ситуация, чтобы иметь приватные переменные и публичные методы.
У нас также могут быть приватные методы, которые определены, например, как вспомогательные методы для других публичных методов.
Здесь мы видим метод check, который вызывается из move и fill, но нам не нужно вызывать этот метод вне класса.
Наконец, мы также ставим ключевое слово public перед классом.
Его смысл станет понятным позже.
Таким образом, извне класса, как правило, мы имеем доступ только к методам, а не к переменным.
Доступ к переменным имеют только методы.
Здесь мы разделили понятия инкапсуляции и сокрытие информации.
Хотя для некоторых эти две концепции идут вместе, то есть инкапсуляция всегда подразумевает сокрытие информации.
Как правило, мы хотим иметь приватные переменные экземпляра и публичные методы, которые получают доступ к этим переменным.
Но мы должны запрограммировать это явно с помощью ключевых слов «private» и «public».
Всегда рекомендуется делать переменные приватными.
А затем определять публичные методы для установки значений переменных и получения значений переменных.
Как правило, название этих двух типов методов соответствует одному и тому же шаблону:
Как правило, имена этих методов начинаются со слова «set» и начинаются со слова «get».
Поэтому эти методы иногда называют сеттеры и геттеры.
Заметим, что в методе setGas мы имеем параметр g, который присваивается полю gas.
Иногда, мы хотим назвать параметр setGas тем же именем, что и переменную экземпляра.
И с этим не возникает никаких проблем.
Однако, если мы хотим отличить визуально параметр от поля, мы можем использовать ключевое слово this и точку перед именем.
Это означает, что это имя относится к полю класса.
В некоторых случаях нам нужно иметь поля класса, которые имеют общее значение для всех объектов в классе.
Эти переменные называются переменными класса, а не переменными экземпляра класса, и они объявляются с помощью ключевого слова «static».
Эти переменные не создаются для каждого созданного объекта класса.
Они создаются только один раз для всех объектов класса.
И если мы изменим это значение, оно будет изменено для всех объектов.
Если мы не хотим, чтобы эта переменная менялась,
Мы можем сделать ее константой, добавив ключевое слово «final».
Мы можем также сделать это и для переменных экземпляра.
По соглашению, имена таких переменных пишутся в верхнем регистре, заглавными буквами.
Как показано здесь.
Значения финальных переменных могут быть установлены только один раз.
Таким образом, теперь у нас есть разные виды переменных.
С одной стороны, у нас есть локальные переменные.
Затем у нас есть переменные экземпляра, которые создаются для каждого объекта или экземпляра класса.
Каждый объект может иметь свое значение, хранящееся в этой переменной.
Мы можем использовать ключевое слово «this» для обозначения этих переменных.
И у нас есть переменные класса, которые создаются только один раз для всех объектов одного класса.
Они объявляются с ключевым словом «static».
Статические переменные инициализируются только один раз, при запуске выполнения кода, при загрузке класса.
Эти переменные будут инициализированы первыми, прежде чем будут инициализированы любые переменные экземпляра.
И если вы хотите сделать переменную экземпляра или переменную класса неизменной, вы добавляете ключевое слово «final».
Данный текст является ознакомительным фрагментом.Область видимости и время жизни переменных.
Под «видимостью переменных» подразумевают места в коде, где к этой переменной можно обратиться. К некоторым переменным можно обращаться отовсюду в программе, к другим только в пределах их класса, к третьим же только внутри одного метода.
В Java существует три вида переменных, основанных на области действия и времени жизни.
Локальная переменная: Локальные переменные объявляются в методах, конструкторах или блоках.
Глобальная переменная / переменная экземпляра: переменные экземпляра объявляются в классе, но вне метода, конструктора или любого блока.
Переменная экземпляра также является переменной объекта, обычно называемой полем или свойством. Они называются объектной переменной. Каждый объект имеет свою собственную копию каждой переменной, и, следовательно, он не влияет на переменную экземпляра, если один объект изменяет значение переменной.
Класс / Статические переменные: переменные класса, также известные как статические переменные, объявляются с ключевым словом static в классе. Статические переменные также используются при объявлении константы вместе с последним ключевым словом.
Переменные создаются при вводе их области действия и уничтожаются при оставлении их области действия.
Переменная не будет сохранять свое значение после выхода из области видимости.
Переменные, объявленные в методе, не будут хранить свои значения между вызовами этого метода. Кроме того, переменная, объявленная в блоке, потеряет свое значение при выходе из блока. Таким образом, время жизни переменной ограничено ее областью действия.
Если объявление переменной включает инициализатор, то эта переменная будет повторно инициализироваться каждый
время вводится блок, в котором он объявлен.
Область видимости и время жизни объектов
Объекты доступны в программе только через ссылки на них. Поэтому область видимости объекта определяется областью видимости ссылок на этот объект (на один объект может быть сколько угодно ссылок).
Время жизни объекта определяется следующим правилом.
Это правило, однако, не утверждает, что объект будет уничтожен, как только пропадет последняя ссылка на него. Просто такой объект становится недоступным и может быть уничтожен.
Вопрос 3. Классы и объекты. Структура класса. Конструкторы класса
Объект в программе — это абстракция реального объекта. Объект обладает атрибутами, поведением и индивидуальностью. Атрибуты определяют основные черты объекта, поведение — действия над объектом, индивидуальность — отличие одного объекта от другого с такими же атрибутами по их конкретным значениям. Например: два кота, у обоих есть шерсть, но у одного шерсть черного цвета, у другого — рыжая.
Класс – это множество объектов с одинаковыми атрибутами и поведением, представляемое в языке программирования в виде абстрактного типа данных, который включает в себя члены класса.
Шаблоном или описанием объекта является класс, а объект представляет экземпляр этого класса. Можно еще провести следующую аналогию. У нас у всех есть некоторое представление о человеке — наличие двух рук, двух ног, головы, туловища и т.д. Есть некоторый шаблон — этот шаблон можно назвать классом. Реально же существующий человек (фактически экземпляр данного класса) является объектом этого класса. Для хранения состояния объекта в классе применяются поля или переменные класса. Для определения поведения объекта в классе применяются методы.
Класс — это компонент языка Java, из которого создаются отдельные объекты.
Класс может содержать в себе типы переменных:
Локальные — переменные, определенные внутри методов, конструкторов или блоков, называются локальными переменными. Переменная будет объявлена и инициализирована в методе, а переменная будет уничтожена после завершения метода.
Переменные экземпляра — это переменные внутри класса, но вне какого-либо метода. Эти переменные инициализируются, когда создается экземпляр класса. К переменным экземпляра можно получить доступ из любого метода, конструктора или блоков этого конкретного класса.
Переменные класса — это переменные, объявленные внутри класса, вне любого метода, с ключевым словом static.
ДКЛ53-Дж. Минимизация области действия переменных — SEI CERT Oracle Coding Standard for Java
Перейти к концу метаданных
Минимизация области действия помогает разработчикам избежать распространенных ошибок программирования, улучшает читаемость кода за счет соединения объявления и фактического использования переменной, а также повышает удобство сопровождения, поскольку не используется. переменные легче обнаруживаются и удаляются. Это также может ускорить восстановление объектов сборщиком мусора и предотвратить нарушения DCL51-J. Не затеняйте и не скрывайте идентификаторы в подобластях.
Несовместимый пример кода
В этом несовместимом примере кода показана переменная, объявленная вне цикла for
.
публичный класс Scope { public static void main(String[] args) { интервал я = 0; для (я = 0; я < 10; я ++) { // Делаем операции } } }
Этот код несовместим, поскольку, хотя переменная i
не используется преднамеренно вне цикла for
, она объявлена в области действия метода. Один из немногих сценариев, где переменная i
необходимо объявить в области действия метода, если цикл содержит оператор break и значение i
должно быть проверено после завершения цикла.
Совместимое решение
По возможности сведите к минимуму область действия переменных. Например, объявите индексы цикла в операторе for
:
public class Scope { public static void main(String[] args) { for (int i = 0; i < 10; i++) { // Содержит объявление // Делаем операции } } }
Несовместимый пример кода
В этом примере несовместимого кода показана переменная count
, которая объявлена вне метода счетчика
, хотя эта переменная не используется вне метода счетчика
.
открытый класс Foo { частный счетчик; частный статический финал int MAX_COUNT = 10; общедоступный счетчик недействительных () { количество = 0; пока (условие()) { /* ... */ если (количество++ > MAX_COUNT) { возвращаться; } } } частное логическое условие () {/* . .. *} // Ссылки на другие методы не учитываются // но несколько других методов ссылаются на MAX_COUNT }
Совместимое решение
В этом совместимом решении поле count
объявлено локальным для метода counter()
:
public class Foo { частный статический финал int MAX_COUNT = 10; общедоступный счетчик недействительных () { количество счетчиков = 0; пока (условие()) { /* ... */ если (количество++ > MAX_COUNT) { возвращаться; } } } частное логическое условие () {/* ... */} // Ссылки на другие методы не учитываются // но несколько других методов ссылаются на MAX_COUNT }
Применимость
Обнаружение локальных переменных, которые объявлены в большей области, чем требуется написанным кодом, является простым и может исключить возможность ложных срабатываний.
Обнаружение нескольких операторов вместо
, использующих одну и ту же индексную переменную, не представляет сложности; он дает ложные срабатывания в необычном случае, когда значение индексной переменной должно сохраняться между циклами.
Библиография
[Bloch 2001] | Item 29, "Minimize the Scope of Local Variables" |
[JLS 2013] | §14.4, "Local Variable Declaration Statements" |
java - Что подразумевается под областью действия переменной?
Что подразумевается под "областью действия" переменной? подумайте о области действия переменной как «область действия конкретной переменной - это диапазон в исходном коде программы, в котором эта переменная распознается компилятором».
Это определение соответствует определению области видимости в спецификации C#; там написано:
Область действия имени — это область текста программы, в пределах которой можно обратиться к объекту, объявленному по имени, без уточнения имени
Обратите внимание, что в спецификации C# указывается, что это имя имеет область действия. Некоторые переменные не имеют имен и, следовательно, не имеют области видимости. И некоторые вещи имеют имена, но не являются переменными; имена классов, имена пространств имен, имена функций и т. д. — все они имеют область видимости.
Область действия локальной переменной часто путают с ее временем жизни . Время жизни локальной переменной иногда связано с ее областью действия; когда управление выходит из области локального (либо обычными средствами, либо через исключение), то локальное может быть уничтожено без чьего-либо уведомления. Однако среде выполнения разрешено укорачивать время жизни локальной переменной , если она может сделать это незаметно. Время выполнения также разрешено , чтобы локальная переменная жила дольше, чем ее область действия. И есть некоторые ситуации, в которых локальная переменная требуется , чтобы жить дальше, когда управление выходит из своей области. (Например, когда локальная переменная является закрытой внешней переменной лямбды. )
Поэтому неразумно использовать «область действия» как синоним «времени жизни». Они часто связаны, но могут быть совершенно разными. Используйте «область» для обозначения «области текста, в которой допустимо имя», а не «периода времени, в течение которого переменная жива». Область видимости — это, по сути, концепция времени компиляции .
В чем именно разница между областью действия переменных в C# и (C99, C++, Java)
Я недостаточно знаком с точными правилами области видимости C, C++ или Java, чтобы дать краткий список различий . Однако я могу указать на некоторые странности C#.
Во-первых, в C# локальная переменная находится в области на протяжении своего блока.
класс С { интервал х; пустота М () { интервал у = х; интервал х = у; } }
В C++ первый "x" означает "this.x", поскольку локальная переменная x не находится в области видимости до ее объявления.