Применение абстрактных классов в Java

Применение абстрактных классов в Java

Иногда суперкласс требуется определить таким образом, чтобы объявить в нем структуру заданной абстракции, не предоставляя полную реализацию каждого ме­тода

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

В таком классе определяется характер методов, которые должны быть реализованы в подклассах. Подобная ситуация мо­жет, например, возникнуть, когда в суперклассе не удается полностью реализовать метод.

Например, посмотрите на следующий код:

Определение метода area() в классе Figure служит лишь в качестве шаблона, не позволяя рассчи­тать и вывести площадь объекта какого-нибудь типа.

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

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

Ведь могут быть и такие ме­тоды, которые должны быть переопределены в подклассе, чтобы подкласс имел хотя бы какой-то смысл.

Рассмотрим в качестве примера класс Triangle. Он ли­шен всякого смысла, если метод area() не определен. В таком случае требуется каким-то образом убедиться, что в подклассе действительно переопределяются все необходимые методы. И для этой цели в Java служит абстрактный метод.

Для того чтобы некоторые методы переопределялись в подклассе, достаточно объявить их с модификатором типа abstract.

Иногда они называются методами под ответственностъю подкласса, поскольку в суперклассе для них никакой реализа­ции не предусмотрено.

Следовательно, эти методы должны быть переопределены в подклассе, где нельзя просто воспользоваться их вариантом, определенным в су­перклассе.

Для объявления абстрактного метода используется приведенная ниже общая форма. Как видите, в этой форме тело метода отсутствует.

Любой класс, содержащий один или больше абстрактных методов, должен быть также объявлен как абстрактный.

Для этого достаточно указать ключевое слово abstract перед ключевым словом class в начале объявления класса.

У аб­страктного класса не может быть никаких объектов. Это означает, что экземпляр абстрактного класса не может быть получен непосредственно с помощью операто­ра new.

Такие объекты были бы бесполезны, поскольку абстрактный класс опреде­лен не полностью. Кроме того, нельзя объявлять абстрактные конструкторы или абстрактные статические методы.

Любой подкласс, производный от абстрактногокласса, должен реализовать все абстрактные методы из своего суперкласса или же сам быть объявлен абстрактным.

Ниже приведен простой пример класса, содержащего абстрактный метод, и класса, реализующего этот метод.

Вывод программы следующий:

Обратите внимание на то, что в этой программе объекты класса А не объяв­ляются. Как отмечалось ранее, получить экземпляр абстрактного класса нельзя.

И еще одно: в классе А реализуется конкретный метод callMeToo(), что вполне допустимо. В абстрактные классы может быть включена реализация какого угодно количества конкретных методов.

Несмотря на то, что абстрактные классы не позволяют получать экземпляры объектов, их все же можно применять для создания ссылок на объекты, поскольку в Java полиморфизм во время выполнения реализован с помощью ссылок на супер­класс.

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

Используя абстрактный класс, можно усовершенствовать созданный ранее класс Figure. Понятие площади неприменимо к неопределенной двумерной фигуре, поэтому в приведенной ниже новой версии программы метод area() объявляется в классе Figure как abstract.

Это, конечно, означает, что метод area() должен быть переопределен во всех классах, производных от класса Figure.

Вывод будет следующим:

Как следует из комментариев в теле метода main(), объявление объектов типа Figure больше не допускается, поскольку теперь этот класс является абстрактным.

И во всех подклассах, производных от класса Figure, должен быть переопределен метод area(). Чтобы убедиться в этом, попытайтесь создать подкласс, в котором метод area() не переопределяется. Это приведет к ошибке во время компиляции.

Если создать объект типа Figure нельзя, то можно хотя бы создать ссылочную переменную типа Figure.

Переменная figref объявлена как ссылка на класс Figure, т.е. ее можно использовать для ссылки на объект любого класса, производного от клас­са Figure.

Как пояснялось ранее, вызовы переопределенных методов разрешаются во время выполнения с помощью ссылочных переменных из суперкласса.

Советуем вам к просмотру следующее видео: