9 июл. 2015 г.

Наследование. Часть 2 – абстрактные классы и методы.

Абстрактный класс – это класс экземпляр которого нельзя создать. Ну и зачем же он тогда может быть нужен? А вот представьте себе нужен таки :)

В ряде ситуаций нужно будет определять суперкласс, который объявляет структуру определенной абстракции без предоставления полной реализации каждого метода. То есть иногда придется создавать суперкласс, определяющий только обобщенную форму, которую будут совместно использовать все его подклассы, добавляя необходимые детали. Такой класс определяет сущность методов, которые должны реализовать подклассы. Например, такая ситуация может возникать, когда суперкласс не в состоянии создать полноценную реализацию метода. Примером может служить класс Number из стандартной библиотеки Java. Посмотрите его на досуге :)

Абстрактные классы объявляются при помощи модификатора abstract. И как можно догадаться они могут содержать абстрактные методы, которые объявляются при помощи этого же модификатора.

Java позволяет определить метод без реализации, объявив его с модификатором abstract. У абстрактного метода нет тела; у него есть только заголовок, заканчивающийся точкой с запятой.

A0001

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

  • Любой класс с абстрактным методом автоматически становится абстрактным и должен быть объявлен как abstract.
  • Нельзя создать ни одного экземпляра абстрактного класса.
  • Экземпляры подклассов абстрактного класса, можно создавать только в том случае, если все методы, объявленные как abstract, замещены и реализованы (то есть имеют тело). Такие классы часто называют реальными, чтобы подчеркнуть тот факт, что они не абстрактные.
  • Если подкласс абстрактного класса, не реализует всех методов, объявленных как abstract, то этот подкласс сам является абстрактным.
  • Методы, объявленные как static, private и final, не могут быть объявлены как abstract, поскольку такие методы не могут быть замещены подклассами. Точно так же класс, объявленный как final, не может содержать методов, объявленных как abstract.
  • Класс может быть объявлен как abstract, даже если он не содержит ни одного абстрактного метода. Такое объявление означает, что реализация класса все еще не закончена и класс будет служить родителем для одного или нескольких подклассов, которые завершат реализацию. Экземпляр такого класса не может быть создан.
  • Можно создавать объектные переменные абстрактных классов, однако такие переменные должны ссылаться на объект неабстрактного подкласса.

A0002Ну а теперь немножко попрактикуемся, чтобы понять получше эту тему. Создадим абстрактный класс животного и от него унаследуем конкретных животных – корову, кошку и собаку.

В абстрактном классе объявим абстрактный метод getSound(), который будет выводить на печать звук который издает животное.

А так же, чтобы знать что за животное издает этот звук мы создадим нормальный (не абстрактный) метод getType(), который будет возвращать тип животного.

В классах наследниках мы уже сделаем для каждого свою реализацию абстрактного метода getSound().

A0003

A0004

A0005

A0006

Ну и собственно сводим теперь все в одну работающую кучу :)

Следует заметить что мы объявили массив ссылок типа Animal. Напоминаю одно из правил – можно создавать объектные ссылки абстрактных классов, но ссылаться они должны на объекты подклассов, что у нас и реализовано.

Каждому из элементов массива мы присваиваем ссылку на объект подкласса класса Animal.

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

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

A0007

Как видим звуки соответствуют животным :)

2 комментария:

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

    ОтветитьУдалить
  2. Да, если вы хотите создавать экземпляр класса наследника. Но от абстрактного класса, так же может унаследоваться и другой абстрактный класс, и тогда не обязательно переопределять все абстрактные методы.

    Интерфейсы и классы это вообще разные типы данных в Java http://pr0java.blogspot.ru/2015/04/java-1.html
    и используются они по разному

    ОтветитьУдалить