Автор оригинала: Pankaj Kumar.
Разница между абстрактным классом и интерфейсом-один из популярных вопросов для интервью. Абстрактный класс и интерфейс являются основной частью языка программирования Java. Выбор интерфейса или абстрактного класса – это дизайнерское решение, с которым сталкивается каждый архитектор.
В своих последних статьях я предоставил как можно больше подробностей об интерфейсе java и абстрактном классе .
В этом посте мы узнаем о разнице между абстрактным классом и интерфейсом и о том, когда следует использовать интерфейс поверх абстрактного класса и наоборот.
Разница между абстрактным классом и интерфейсом
ключевое слово abstract
используется для создания абстрактного класса, и его также можно использовать с методами, тогда как ключевое словоinterface
используется для создания интерфейса, и его нельзя использовать с методами.- Подклассы используют ключевое слово
extends
для расширения абстрактного класса, и им необходимо обеспечить реализацию всех объявленных методов в абстрактном классе, если подкласс также не является абстрактным классом, тогда как подклассы используют ключевое словоimplements
для реализации интерфейсов и должны обеспечивать реализацию всех методов, объявленных в интерфейсе. - Абстрактные классы могут иметь методы с реализацией, в то время как интерфейс обеспечивает абсолютную абстракцию и не может иметь никаких реализаций методов. Обратите внимание, что начиная с Java 8 и далее мы можем создавать методы по умолчанию и статические методы в интерфейсе, содержащем реализации методов.
- Абстрактные классы могут иметь конструкторы, но интерфейсы не могут иметь конструкторов.
- Абстрактный класс обладает всеми функциями обычного класса java, за исключением того, что мы не можем создать его экземпляр. Мы можем использовать ключевое слово
abstract
для создания абстрактного класса, но интерфейсы совершенно другого типа и могут содержать только общедоступные статические конечные константы и объявления методов. - Методы абстрактных классов могут иметь модификаторы доступа как общедоступные, частные, защищенные, статические, но методы интерфейса неявно являются общедоступными и абстрактными, мы не можем использовать какие-либо другие модификаторы доступа с методами интерфейса.
- Подкласс может расширять только один абстрактный класс, но он может реализовывать несколько интерфейсов.
- Абстрактные классы могут расширять другие классы и реализовывать интерфейсы, но интерфейс может расширять только другие интерфейсы.
- Мы можем запустить абстрактный класс, если у него есть метод
main ()
, но мы не можем запустить интерфейс, потому что у них не может быть реализации метода main. - Интерфейсы используются для определения контракта для подклассов, в то время как абстрактный класс также определяет контракт, но он может предоставлять другие реализации методов для использования подклассами.
Это все из-за разницы между интерфейсом и абстрактными классами , теперь мы можем перейти к тому, чтобы узнать, когда нам следует использовать интерфейс над абстрактным классом и наоборот.
Интерфейс или Абстрактный класс
Выбор между интерфейсом или абстрактным классом для предоставления контракта для подклассов является дизайнерским решением и зависит от многих факторов. Давайте посмотрим, когда интерфейсы являются лучшим выбором и когда мы можем использовать абстрактные классы.
- Java не поддерживает наследование на нескольких уровнях классов, поэтому каждый класс может расширять только один суперкласс. Но класс может реализовывать несколько интерфейсов. Таким образом, в большинстве случаев интерфейсы являются хорошим выбором для обеспечения основы иерархии классов и контракта. Кроме того, кодирование с точки зрения интерфейсов является одной из лучших практик для кодирования на java.
- Если в контракте много методов, то абстрактный класс более полезен, потому что мы можем предоставить реализацию по умолчанию для некоторых методов, которые являются общими для всех подклассов. Также, если подклассам не нужно реализовывать определенный метод, они могут избежать предоставления реализации, но в случае интерфейса подкласс должен будет предоставить реализацию для всех методов, даже если это бесполезно, а реализация-просто пустой блок.
- Если наш базовый контракт продолжает меняться, то интерфейсы могут вызвать проблемы, потому что мы не можем объявить дополнительные методы интерфейсу без изменения всех классов реализации, с помощью абстрактного класса мы можем предоставить реализацию по умолчанию и изменить только классы реализации, которые на самом деле будут использовать новые методы.
Используйте абстрактные классы и интерфейс как
Использование интерфейсов и абстрактных классов вместе-лучший подход к проектированию системы. Например, в JDK java.util.Список
– это интерфейс, содержащий множество методов, поэтому существует абстрактный класс java.util.AbstractList
, который обеспечивает скелетную реализацию для всех методов интерфейса списка, так что любой подкласс может расширять этот класс и реализовывать только необходимые методы.
Мы всегда должны начинать с базового интерфейса и определять методы, которые должен реализовывать каждый подкласс, а затем, если есть некоторые методы, которые должен реализовывать только определенный подкласс, мы можем расширить базовый интерфейс и создать новый интерфейс с помощью этих методов.
Подклассы будут иметь возможность выбирать между базовым интерфейсом или дочерним интерфейсом для реализации в соответствии с его требованиями.
Если количество методов значительно увеличивается, неплохо было бы предоставить скелетный абстрактный класс, реализующий дочерний интерфейс и предоставляющий подклассам гибкость при выборе между интерфейсом и абстрактным классом.
Изменения интерфейса Java 8
Начиная с Java 8 и далее, у нас могут быть реализации методов в интерфейсах. Мы можем создавать как стандартные, так и статические методы в интерфейсах и предоставлять для них реализацию.
Это позволило преодолеть разрыв между абстрактными классами и интерфейсами, и новые интерфейсы-это правильный путь, потому что мы можем расширить его еще больше, предоставив реализации по умолчанию для новых методов.
Для получения более подробной информации ознакомьтесь со статическими методами интерфейса Java 8 по умолчанию .