Вход/Регистрация
Java: руководство для начинающих
вернуться

Шилдт Герберт

Шрифт:

И еще одно, последнее замечание. Обратите внимание на то, что в классе TwoDShape по-прежнему присутствуют определения методов showDim и getName и перед их именами нет модификатора abstract. В абстрактные классы вполне допускается (и часто практикуется) включать конкретные методы, которые могут быть использованы в своем исходном виде в подклассе. А переопределению в подклассах подлежат только те методы, которые объявлены как abstract. Использование ключевого слова final

Какие бы богатые возможности ни представляли механизмы наследования и переопределения методов, иногда требуется запретить их действие. Допустим, создается класс, в котором инкапсулированы средства управления некоторым устройством. Кроме того, в этом классе пользователю может быть разрешено инициализировать устройство, чтобы воспользоваться некоторой секретной информацией. В таком случае пользователи данного класса не должны иметь возможность переопределять метод инициализации устройства. Для этой цели в Java предоставляется ключевое слово final, позволяющее без труда запретить переопределение метода или наследование класса. Предотвращение переопределения методов

Для того чтобы предотвратить переопределение метода, в начале его объявления нужно указать модификатор доступа final. Переопределять объявленные подобным образом методы нельзя. Ниже приведен фрагмент кода, демонстрирующий использование ключевого слова final для подобных целей. class А { final void meth { System.out.println("This is a final method."); } } class В extends А { void meth { // Ошибка! Переопределить метод нельзя. System.out.println("Illegal!") ; } }

Поскольку метод meth объявлен как final, его нельзя переопределить в классе В. Если вы попытаетесь сделать это, возникнет ошибка при компиляции программы. Предотвращение наследования

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

Ниже приведен пример класса, подклассы которого создавать запрещено. final class А { // ... } // Следующее определение класса недопустимо. class В extends А { // Ошибка! Создать подкласс от класса А нельзя. // . . . }

Как следует из комментариев к данному примеру, недопустимо, чтобы класс В наследовал от класса А, так как последний определен как final. Применение ключевого слова final к переменным экземпляра

Помимо рассмотренных ранее примеров использования, ключевое слово final можно применять и к переменным экземпляра. Подобным способом создаются именованные константы. Если имени переменной предшествует модификатор final, то значение этой переменной не может быть изменено на протяжении всего времени выполнения программы. Очевидно, что подобным переменным нужно присваивать начальные значения. В главе 6 был рассмотрен простой класс ErrorMsg для обработки ошибок. В нем устанавливается соответствие между кодами ошибок и символьными строками сообщений об ошибках. Ниже приведен усовершенствованный вариант этого класса, в котором для создания именованных констант применяется модификатор final. Теперь, вместо того чтобы передавать методу getErrorMsg числовое значение, например 2, достаточно указать при его вызове именованную целочисленную константу DISKERR. // Возврат объекта типа String, class ErrorMsg { // Коды ошибок. // Константы объявляются с помощью ключевого слова final. final int OUTERR = 0; final int INERR = 1; final int DISKERR = 2; final int INDEXERR = 3; String msgs[] = { "Output Error", "Input Error", "Disk Full", "Index Out-Of-Bounds" }; // возвратить сообщение об ошибке String getErrorMsg(int i) { if(i >=0 & i < msgs.length) return msgs[i]; else return "Invalid Error Code"; } } class FinalD { public static void main(String args[]) { ErrorMsg err = new ErrorMsg; // При вызове метода используются константы, // объявленные с помощью ключевого слова final. System.out.println(err.getErrorMsg(err.OUTERR)); System.out.println(err.getErrorMsg(err.DISKERR)); } }

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

Многие программирующие на Java пользуются именами констант типа final, составленными полностью из прописных букв, как в предыдущем примере. Но это не строгое правило, а только принятый стиль программирования. Класс Object

В Java определен специальный класс Object. По умолчанию он считается суперклассом всех остальных классов. Иными словами, все классы являются подклассами, производными от класса Object. Это означает, что переменная ссылки на объект типа Object может ссылаться на объект любого класса. Более того, переменная ссылки на объект типа Object может также ссылаться на любой массив, поскольку массивы реализованы в виде классов.

В классе Object определены перечисленные ниже методы, доступные в любом объекте. Метод Назначение Object clone Создает новый объект, аналогичный клонируемому объекту boolean equals (Object объект) Определяет равнозначность объектов void finalize Вызывается перед тем, как неиспользуемый объект будет удален системой "сборки мусора" Class<?> getClass Определяет класс объекта во время выполнения int hashCode Возвращает хеш-код, связанный с вызывающим объектом void notify Возобновляет работу потока, ожидающего уведомления от вызывающего объекта void notifyAll Возобновляет работу всех потоков, ожидающих уведомления от вызывающего объекта String toString Возвращает символьную строку, описывающую объект void wait Ожидает исполнения другого потока void wait (long миллисекунды) Ожидает исполнения другого потока void wait (long миллисекунды, int наносекунды) Ожидает исполнения другого потока

Методы getClass, notify, notifyAll и wait объявлены как final, а остальные методы можно переопределять в подклассах. Некоторые из этих методов будут описаны далее в этой книге. Два из них — equals и toString — заслуживают особого внимания. Метод equals сравнивает два объекта. Если объекты равнозначны, то он возвращает логическое значение true, иначе — логическое значение false. Метод toString возвращает символьную строку, содержащую описание того объекта, которому принадлежит этот метод. Он автоматически вызывается в том случае, если объект передается методу println в качестве параметра. Во многих классах этот метод переопределяется. В этом случае описание специально подбирается для конкретных типов объектов, которые в них создаются.

Обратите внимание на необычный синтаксис, описывающий значение, возвращаемое методом getClass . Это обобщенный тип. С помощью обобщений в Java можно указывать в качестве параметра тип данных, используемый в классе или методе. Более подробно обобщения рассматриваются в главе 13. Упражнение для самопроверки по материалу главы 7

Имеет ли суперкласс доступ к членам подкласса? Имеет ли подкласс доступ к членам суперкласса?

Создайте подкласс Circle, производный от класса TwoDShape. В нем должен быть определен метод area , вычисляющий площадь круга, а также конструктор с ключевым словом super для инициализации членов, унаследованных от класса TwoDShape.

  • Читать дальше
  • 1
  • ...
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: