Java Уроки: Абстрактные классы и методы с нуля

Что такое абстрактный класс?

Абстрактный класс реализует минимальный функционал. На его основе нельзя создавать объекты. Он сам по себе не реализует методы; он лишь описывает шаблоны для методов, указывая на существование методов, реализация которых будет происходить в классах-наследниках.

Зачем нужны абстрактные классы?

Рассмотрим пример: есть класс Транспорт, а также классы Car и Truck. Объекты никогда не будут создаваться непосредственно на основе класса Транспорт. Автомобиль создаётся на основе класса Car, грузовик – на основе Truck. Если нужно создать мотоцикл, создаётся класс Motorcycle и объекты мотоциклов создаются на его основе. То же самое относится к самолётам, лодкам и другим видам транспорта.

Поэтому класс Транспорт можно объявить абстрактным. Это предотвратит создание объектов на его основе программным путём (попытка создания объекта вызовет ошибку). Внутри абстрактного класса можно описывать обычные методы и абстрактные методы, не требующие реализации. Для крупных базовых классов абстракция логична, так как объекты на основе таких классов не создаются. Абстрактный класс описывает общий функционал, а реализация этого функционала происходит в классах-наследниках.

Создание абстрактного класса в Java

Чтобы создать абстрактный класс, перед ключевым словом class добавляется ключевое слово abstract. Например:

abstract class Транспорт {
    // ...
}

После добавления abstract класс остаётся без изменений, но создание объектов на его основе становится невозможным. Если удалить abstract, объект класса Транспорт создаётся без ошибок. После добавления abstract попытка создания объекта приведёт к ошибке компиляции.

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

Транспорт транспорт = new Car(); // Это допустимо

Но создание объекта непосредственно от абстрактного класса (Транспорт транспорт = new Транспорт();) невозможно.

Абстрактные методы

Главная особенность абстрактных классов — возможность создания абстрактных методов. Например:

abstract void move(float speed);

Здесь:

  • abstract указывает, что метод абстрактный.
  • Метод не имеет реализации (тело метода отсутствует).
  • Метод может принимать параметры (в данном случае – float speed).

Если класс наследует абстрактный класс, он обязан реализовать все абстрактные методы родительского класса. В противном случае будет ошибка компиляции. Для реализации абстрактного метода используется аннотация @Override:

@Override
void move(float speed) {
    System.out.println("Объект движется со скоростью: " + speed);
}

Зачем использовать абстрактные методы, если можно создать обычные методы в классах-наследниках? Абстрактные методы служат напоминанием о необходимости реализации определённого функционала в классах-наследниках. Это особенно полезно при разработке больших проектов, где легко забыть о реализации какой-либо части функциональности. Например, в игре с различными транспортными средствами (машины, лодки, самолёты) все они должны иметь метод передвижения, но реализация этого метода будет разной. Абстрактный метод в базовом классе гарантирует, что этот метод будет реализован во всех классах-наследниках.

Пример с несколькими абстрактными методами

Можно добавить несколько абстрактных методов, например, stop():

abstract boolean stop();

Этот метод может возвращать true, если объект остановлен, и false в противном случае. Реализация также потребуется во всех классах-наследниках.

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

Что будем искать? Например,программа