Каковы различия между ними? Теперь, когда Java 8 включает методы по умолчанию в интерфейсах, нужны ли вам вообще абстрактные классы?

Давайте рассмотрим атрибуты абстрактного класса:

  • они могут включать или не включать абстрактные методы
  • если класс включает абстрактные методы, то сам класс должен быть объявлен абстрактным

Теперь сходство между абстрактным классом и интерфейсом:

  • может содержать смесь методов с реализацией или без нее
  • оба не могут быть созданы

Различия между ними:

Абстрактный класс:

  • можно объявлять поля, которые не являются статическими и окончательными
  • может определять общедоступные, защищенные и частные методы
  • может расширять только один класс (для любого класса)

Интерфейс:

  • все поля автоматически статичны и окончательны
  • методы автоматически становятся общедоступными
  • методы неявно абстрактны, если не объявлено иначе
  • может реализовать множество интерфейсов

И когда вы должны рассмотреть возможность использования каждого из них:

Абстрактный класс:

  • хотите разделить код между тесно связанными классами
  • ожидайте, что класс, который расширяет абстрактный класс, будет иметь много общих полей и методов или потребует модификаторов доступа, отличных от общедоступных
  • хотите объявить нестатические и неконечные поля. Также позволяет вам определять методы, которые могут получать доступ и изменять состояние объекта, которому они принадлежат.

Интерфейс:

  • ожидать, что несвязанные классы будут реализовывать интерфейс (например, интерфейс Comparable и Cloneable реализуется многими несвязанными классами)
  • хотите указать поведение, но не заботитесь о том, кто его реализует
  • хотите воспользоваться преимуществами множественного наследования

Обратите внимание, что в коде «расширяет» стоит перед «реализует», иначе вы получите ошибку компилятора, например class A extends B implements C .