Задумался сегодня над таким вопросом. В языке программирования Java существуют такие понятия как абстрактный класс и интерфейс. Это очень похожие сущности за некоторыми исключениями.
В Java до 8 версии отличия следующие: абстрактный класс — это прежде всего класс, а значит, не поддерживает множественное наследование. А вот интерфейсы можно имплементить бесконечно. В абстрактном классе можно инкапсулировать абсолютно любое состояние, а вот интерфейс себе такого позволить не может. В абстрактном классе можно задавать дефолтную логику, а в интерфейсе нет. Это пожалуй ключевые отличия.
Все логично. Вот вам абстрактный класс, вот вам интерфейс. Абстрактный класс как шаблон для не определенных объектов, а интерфейс, как контракт о том, что класс должен делать.
С 8 версии ЯП, в интерфейсы добавили возможность устанавливать состояния и добавлять логику в методы.
Вопрос — чем же теперь эти две сущности отличаются? И как понять, где использовать абстрактный класс, а где интерфейс?
Придумал сценарий при котором "дефолтная" логика в интерфейсе может быть полезна.
Единообразие ошибки not implemented, если какая часть интерфейса не реализована.
И как понять, где использовать абстрактный класс, а где интерфейс?
Так же, как и раньше. Интерфейс - просто контракт, как правильно было сказано.
Мало ли чем они там в Java8 упоролись, концепция ООП не должна из-за них страдать.
Ну и, классика, следуй принципам SOLID, не смотря на особенности каких-то ЯП какими бы они ни были.
в интерфейсы добавили возможность устанавливать состояния и добавлять логику в методы
в реальной жизни с таким не сталкивался. Теоретически может упростить разработку. В интерфейсе мы описываем возможности объектов и если у разных классов может быть одна реализация метода, почему ее не записать сразу в интерфейсе? Но случай где это будет реально полезно мне придумать сложно
Это же сделали в основном для того, чтобы не реализовывать интерфейсы которые тебе не нужны, но которые являются частью чего то тебе нужного, у таких интерфейсов есть метод по умолчанию.
1. Класс может иметь поля (состояние), интерфейс нет. Вот это первое и главное различие
2. Интерфейс не может иметь протектед и приватные методы, класс - может.
А вообще в интерфейсы можно писать методы с реализацией, чтобы прямо в интерфейсе задокументировать что "вот этот метод он как бы не самостоятельный метод, он реализуется поверх других методов интерфейса. Но он часто используется, он удобный, поэтому вот - держите прямо в интерфейсе". Ну и при необходимости в классе можно перекрыть этот метод, например, чтобы предоставить оптимизированную версию.
Еще посмотрите extension functions в Котлине - придуманы с той же идеей, хотя имеют свои преимущества (легко добавить к существующему интерфейсу/классу) и недостатки (нельзя перекрыть в производном классе)