Sealed интерфейсы — это относительно новая возможность в Kotlin (с версии 1.5), предназначенная для ограничения набора реализаций интерфейса в пределах одного файла. Изначально в Kotlin существовали sealed классы, которые обеспечивали строгий контроль над иерархией наследования, облегчая исчерпывающую обработку (например, в when-выражениях).
Проблема заключалась в том, что иногда архитектуре требовался не базовый класс, а интерфейс с тем же ограничением по количеству реализаций. До появления sealed интерфейсов единственным способом вписаться в ограничения компилятора было использовать sealed class, что не всегда удачно вписывалось в модель предметной области, особенно при необходимости множественного наследования или декомпозиции поведения на интерфейсы.
Решение: Sealed интерфейсы позволяют определить интерфейс, все реализации которого должны быть объявлены внутри одного файла. Это повышает безопасность кода и облегчает контроль и навигацию по иерархии состояний или событий.
Пример кода:
sealed interface NetworkState class Success(val data: String) : NetworkState class Error(val code: Int) : NetworkState object Loading : NetworkState
Ключевые особенности:
Можно ли sealed интерфейс реализовать вне того файла, где он объявлен?
Нет. Как и sealed классы, sealed интерфейсы можно реализовать только в том же самом файле, что и их объявление. За пределами файла попытка реализовать такой интерфейс приведет к ошибке компиляции.
Можно ли sealed интерфейс наследовать от класса?
Нет, интерфейсы могут наследоваться только от других интерфейсов. Но sealed интерфейс может наследоваться от другого (sealed) интерфейса.
Поддерживает ли sealed интерфейс множественную реализацию?
Да, класс внутри этого же файла может реализовать несколько sealed интерфейсов или even наследовать sealed интерфейс и sealed class одновременно, если это допустимо по правилам языка.
В системе обработки сетевых событий разработчик использует обычные интерфейсы и sealed классы вперемешку, результатом становится «грязная» иерархия и дублирование кода. when-выражения вынуждены содержать ветку else.
Плюсы:
Минусы:
В этом же приложении переходят на sealed interface NetworkEvent, помещая все реализации в один файл. Теперь when-выражения по NetworkEvent требуют обработки всех случаев. Код становится более читаемым, поддерживаемым и безопасным.
Плюсы:
Минусы: