Использование интерфейсов и абстрактных классов в Java
Абстракция является одной из ключевых основ объектно-ориентированного программирования. Она позволяет
скрыть сложности реализации, предоставляя функциональные возможности через более простые интерфейсы.
В Java мы достигаем абстракции, используя либо интерфейс, либо абстрактный класс.
В этой статье мы обсудим, когда использовать интерфейс, а когда абстрактный класс при разработке приложений.
Кроме того, рассмотрим ключевые различия между ними и какой из них выбрать в конкретной ситуации.
Класс vs Интерфейс
Во-первых, давайте рассмотрим различия между обычным классом и интерфейсом.
Класс — это определяемый пользователем тип, который действует как схема для создания объекта.
Он может иметь свойства и методы, которые представляют состояния и поведение объекта соответственно.
Интерфейс также является определяемым пользователем типом, который синтаксически похож на класс.
Он может содержать набор констант полей и сигнатур методов, которые будут переопределены классами, реализующими интерфейс.
В дополнение к этому, новые функции Java 8 поддерживают статические методы и методы по умолчанию в интерфейсах
для поддержки обратной совместимости. Методы в интерфейсе неявно абстрактны, если
они не являются статическими или не являются стандартными, и все они являются общедоступными.
А начиная с Java 9, мы также можем добавлять приватные методы в интерфейсы.
Интерфейс vs Абстрактный класс
Абстрактный класс — это не что иное, как класс, который объявляется с использованием ключевого слова abstract.
Также мы можем объявлять методы с использованием ключевого слова abstract (абстрактный метод), что
заставляет подклассы этого класса реализовывать все объявленные методы.
Также, если класса содержит хотя бы один абстрактный метод, то и сам класс должен быть абстрактным.
Абстрактные классы не имеют ограничений на модификаторы полей и методов, в то время как в интерфейсе
все они являются общедоступными (public) по умолчанию. В абстрактном классе могут быть блоки статической инициализации ,
тогда как в интерфейсе их быть не может. Абстрактные классы также могут иметь конструкторы,
которые будут вызываться во время создания экземпляра дочернего объекта.
Java 8 представила функциональные интерфейсы — интерфейс с одним абстрактным методом.
Любой интерфейс с одним абстрактным методом, отличным от статических методов и методов по умолчанию, считается функциональным интерфейсом.
Мы можем использовать эту функцию, чтобы ограничить количество объявляемых абстрактных методов.
Абстрактные классы в некотором смысле аналогичны интерфейсам:
- Мы не можем создать экземпляр ни одного из них. т. е. мы не можем использовать оператор new ABSTRACT_CLASS_NAME()
непосредственно для создания экземпляра объекта. Если бы мы использовали вышеупомянутое утверждение,
нам пришлось бы переопределить все методы, использующие анонимный класс - Они оба могут содержать набор методов, объявленных и определенных с их реализацией или
без нее. т.е. статические методы и методы по умолчанию (определенные) в интерфейсе, методы экземпляра (определенные)
в абстрактном классе, абстрактные методы (объявленные) в них обоих
Когда использовать интерфейс?
- Если проблема должна быть решена с использованием множественного наследования и состоит из большой иерархии классов
- Когда несвязанные классы реализуют наш интерфейс. Например, Comparable предоставляет метод compareTo(), который может быть переопределен для сравнения двух объектов
- Когда функциональные возможности приложения должны быть определены как контракт, но не важно, кто будет реализовывать поведение. т. е. реализация интерфейса остается за поставщиком
- Рассмотрите возможность использования интерфейса, когда в задаче делается утверждение «A способен [сделать это]». Например, «Clonable способен клонировать объект», «Drawable способен рисовать форму» и т.д.
В этой статье мы сделали обзор интерфейсов и абстрактных классов и рассмотрели ключевые различия между ними.