Каковы различия между ними? Теперь, когда Java 8 включает методы по умолчанию в интерфейсах, нужны ли вам вообще абстрактные классы?
Давайте рассмотрим атрибуты абстрактного класса:
- они могут включать или не включать абстрактные методы
- если класс включает абстрактные методы, то сам класс должен быть объявлен абстрактным
Теперь сходство между абстрактным классом и интерфейсом:
- может содержать смесь методов с реализацией или без нее
- оба не могут быть созданы
Различия между ними:
Абстрактный класс:
- можно объявлять поля, которые не являются статическими и окончательными
- может определять общедоступные, защищенные и частные методы
- может расширять только один класс (для любого класса)
Интерфейс:
- все поля автоматически статичны и окончательны
- методы автоматически становятся общедоступными
- методы неявно абстрактны, если не объявлено иначе
- может реализовать множество интерфейсов
И когда вы должны рассмотреть возможность использования каждого из них:
Абстрактный класс:
- хотите разделить код между тесно связанными классами
- ожидайте, что класс, который расширяет абстрактный класс, будет иметь много общих полей и методов или потребует модификаторов доступа, отличных от общедоступных
- хотите объявить нестатические и неконечные поля. Также позволяет вам определять методы, которые могут получать доступ и изменять состояние объекта, которому они принадлежат.
Интерфейс:
- ожидать, что несвязанные классы будут реализовывать интерфейс (например, интерфейс Comparable и Cloneable реализуется многими несвязанными классами)
- хотите указать поведение, но не заботитесь о том, кто его реализует
- хотите воспользоваться преимуществами множественного наследования
Обратите внимание, что в коде «расширяет» стоит перед «реализует», иначе вы получите ошибку компилятора, например class A extends B implements C
.