Статья

Абстрактные классы в Java

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

Ключевые понятия

Прежде чем углубиться в вопрос о том, когда следует использовать абстрактные классы, давайте рассмотрим их наиболее важные характеристики:
  • Мы определяем абстрактный класс с модификатором abstract, предшествующим ключевому слову class
  • Абстрактный класс может быть подклассом, но нельзя создать объект абстрактного класса
  • Если класс содержит один или несколько абстрактных методов, то сам класс должен быть объявлен абстрактным
  • В абстрактном классе могут быть объявлены как абстрактные, так и конкретные методы
  • Подкласс, производный от абстрактного класса, должен либо реализовывать все абстрактные методы базового класса, либо сам быть абстрактным
Чтобы лучше понять эти концепции, мы приведем простой пример.
Давайте сделаем так, чтобы наш базовый абстрактный класс определял API настольной игры:
public abstract class BoardGame {

    //... определния полей и конструкторов

    public abstract void play();

    //... конкретные методы
}
Затем мы можем создать подкласс, который реализует метод play:
public class Chess extends BoardGame {

    public void play() {
        //... реализция
    }
}

Когда нужно использовать абстрактные классы

Теперь давайте проанализируем несколько типичных сценариев, в которых мы должны предпочесть абстрактные классы интерфейсам и конкретным классам:
  • Мы хотим инкапсулировать некоторую общую функциональность в одном месте (повторное использование кода), которую будут совместно использовать несколько связанных подклассов
  • Нам нужно частично определить API, который наши подклассы могут легко расширять и уточнять
  • Подклассы должны наследовать один или несколько общих методов или полей с модификаторами защищенного доступа
Все эти сценарии являются хорошими примерами полного, основанного на наследовании соблюдения принципа открытости/закрытости.
Более того, поскольку использование абстрактных классов неявно имеет дело с базовыми типами и подтипами, мы также используем преимущества полиморфизма.
Обратите внимание, что повторное использование кода является очень веской причиной для использования абстрактных классов, если сохраняется связь “is-а” в иерархии классов.
В Java 8 появились default методы, которые иногда могут заменить необходимость создания абстрактного класса.
java