Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

Использование ключевого слова final для предотвращения переопределения




Использование ключевого слова final для предотвращения переопределения

Хотя переопределение методов – одно из наиболее мощных средств Java, в некоторых случаях его желательно избежать. Чтобы запретить переопределение метода, в начале его объявления необходимо указать ключевое слово final. Методы, объявленные как final, переопределяться не могут. Следующий фрагмент кода иллюстрирует это применениеключевого слова final.

class A {

final void meth() {

System. out. println(" Это метод final. " );

}

}

class B extends A {

void meth() { // ОШИБКА! Этот метод не может быть переопределен.

System. out. println(" Не допускается! " );

}

}

Поскольку метод meth() объявлен как final, он не может быть переопределен в классе B. Попытка выполнить это переопределение приведет к ошибке времени компиляции.

Иногда методы, объявленные как final, могут способствовать увеличению производительности программы. Компилятор вправе вставлять вызовы этих методов непосредственно в строку, поскольку он “знает”, что они не будут переопределены подклассом. Часто при вызове небольшого метода типа final компилятор Java может копировать байт-код подпрограммы непосредственно в строку скомпилированного кода вызывающего метода, тем самым снижая значительные накладные расходы системных ресурсов, связанные с вызовом метода. Помещение методов типа final в строку вызывающего кода – лишь потенциальная возможность. Обычно Java разрешает вызовы методов динамически, во время выполнения. Такой подход называют поздним связыванием. Однако поскольку методы типа final не могут переопределяться, обращение к такому методу может быть разрешено во время компиляции. Этот подход называют ранним связыванием.

Использование ключевого слова final для предотвращения наследования

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

Ниже приведен пример класса типа final.

final class A {

//...

}

// Следующий класс недопустим.

class B extends A { // ОШИБКА! Класс A не может иметь подклассы.

//...

}

Как видно из комментария, класс B не может наследовать от класса A, поскольку A объявлен как final.

Класс Object

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

Методы getClass(), notify(), notifyAll() и wait() объявлены как final. Остальные методы можно переопределять. Обратите внимание на два метода: equals() и toString(). Метод equals() сравнивает содержимое двух объектов. Если объекты эквивалентны, он возвращает значение true, если нет – false. Точное определение равенства зависит от типа сравниваемых объектов. Метод toString() возвращает строку, которая содержит описание объекта, по отношению к которому он вызван. Кроме того, этот метод автоматически вызывается при выводе объекта с помощью метода println(). Многие классы переопределяют этот метод. Это позволяет им приспосабливать описание специально для создаваемых ими объектных типов.

· Object clone(): Создает новый объект, не отличающийся от клонируемого объекта

· boolean equals(Object object): Определяет, равен ли один объект другому

· void finalize(): Вызывается перед удалением неиспользуемого объекта

· Class getClass(): Получает класс объекта во время выполнения

· int hashCode(): Возвращает хеш-код, связанный с вызывающим объектом

· void notify(): Возобновляет выполнение потока, который ожидает вызывающего объекта

· void notifyAll(): Возобновляет выполнение всех потоков, которые ожидают вызывающего объекта

· String toString(): Возвращает строку, которая описывает объект

· void wait(), void wait(long milliseconds), void wait(long milliseconds
int nanoseconds): Ожидает другого потока выполнения

Интерфейсы и пакеты

Пакеты – это контейнеры классов, которые используются для сохранения изолированности пространства имен класса. Например, пакет позволяет создать класс по имени List, который можно хранить в отдельном пакете, не беспокоясь о возможных конфликтах с другим классом List, хранящимся в каком-то другом месте. Пакеты хранятся в иерархической структуре и явно импортируются в определения новых классов.

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

Поделиться:





Воспользуйтесь поиском по сайту:



©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...