Статьи

Изучите Java для разработки под Android: подробнее о внутренних классах

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

В Java классы могут быть вложены друг в друга для упорядоченной организации данных и функций. Анонимные внутренние классы — это, по сути, сокращение от разработчика, позволяющее разработчику создавать, определять и использовать пользовательский объект за один раз. Анонимные внутренние классы часто используются в Android для определения обработчиков для элементов управления, определения и запуска новых потоков, а также создания и возврата пользовательских объектов в методы, не загромождая код ненужными настройками.

Подробное обсуждение вложенных и внутренних классов, включая анонимные внутренние классы, см. В нашем учебном пособии под названием Изучение Java для разработки под Android: внутренние классы.

Иногда вы хотите получить доступ к информации, доступной за пределами внутреннего класса. Рассмотрим следующий пример. У вас есть экран с двумя элементами управления: кнопка и TextView. Каждый раз, когда пользователь нажимает на элемент управления Button, элемент управления TextView обновляется с использованием текущего времени. В классе Activity, связанном с этим макетом, вы можете реализовать эту функцию следующим образом:

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

К сожалению, это не скомпилируется. Вместо этого вы получите ошибку компиляции «Невозможно обратиться к неконечной переменной myTextview внутри внутреннего класса, определенного в другом методе». Как следует из ошибки, вам нужно сделать финальную переменную TextView, чтобы она была доступна внутри метода onClick () внутреннего класса:

Этот код будет действительно скомпилирован и запущен, как и ожидалось.

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

  • Вы не можете изменить значение (r-значение) конечной переменной. Например, если вы попытаетесь присвоить переменную myTextview другому элементу управления в методе onClick () внутреннего класса, вы получите ошибку компиляции: «Конечная локальная переменная myTextview не может быть назначена, поскольку она определена в включающем типе. »
  • Вы можете вызывать методы последней переменной, если у вас есть доступ. Это то, что позволяет нам вызывать метод setText () TextView. Это не меняет значение переменной myTextview, оно просто меняет то, что отображается на экране — тонкое, но важное отличие. (Причина этого в том, что ссылка на объект не может измениться, но сам объект может измениться с помощью своих методов.)
  • Значение окончательной переменной не нужно знать во время компиляции, тогда как статическая переменная известна во время компиляции.
  • Ключевое слово final часто соединяется со статической переменной (полем или переменной, привязанной ко всем экземплярам класса, а не к одному экземпляру), чтобы создать константу для использования в вашем приложении, например: public static final String DEBUG_TAG, используемая для Цели ведения журнала LogCat на протяжении всей вашей деятельности.

В Java вы можете использовать специальную ссылку this для ссылки на конкретный экземпляр объекта. Так что же происходит, когда у вас есть класс с внутренним классом или, в этом отношении, анонимный внутренний класс? Ну, внутренний класс может обращаться к специальному экземпляру this экземпляра окружающего класса, и у него также есть собственная ссылка this. Чтобы получить доступ к экземпляру this для внутреннего класса, просто используйте синтаксис this. Чтобы получить доступ к этому экземпляру включающего класса, вам нужно прикрепить имя включающего класса, затем точку, затем this. Например:

Взгляните на полную реализацию анонимного внутреннего класса, как обсуждалось выше, в полном контексте включающего его класса, здесь называемого ClassChaosActivity:

Вывод журнала для нажатия кнопки происходит следующим образом:

Как видите, ключевое слово this само по себе относится к «ближайшему» классу — внутреннему классу. Хотя внутренний класс является анонимным, Java присваивает ему номер ClassChaosActivity $ 1, чтобы отслеживать его. Хотя это само по себе бесполезно для разработчиков, это показывает, что анонимный внутренний класс обрабатывается внутренне как любой другой класс. Тем временем мы получаем доступ к экземпляру включающего класса, используя синтаксис ClassChaosActivity.this.

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

Разработчики мобильных приложений Лорен Дарси и Шейн Кондер являются соавторами нескольких книг по разработке Android: углубленная книга по программированию под названием « Разработка беспроводных приложений для Android» и « Разработка Android-приложений Sams TeachYourself за 24 часа» . Когда они не пишут, они тратят свое время на разработку мобильного программного обеспечения в своей компании и оказание консультационных услуг. С ними можно связаться по электронной почте [email protected] , через их блог на androidbook.blogspot.com и в Twitter @androidwireless .

Купить Android-разработку беспроводных приложений, 2-е издание Купить Sam's Teach Yourself для Android-разработки приложений в течение 24 часов Код Мамламбо в Код-Каньоне