Sealed interface в Java
Интерфейс с модификатором sealed задаёт запечатанный
контракт без обязательного общего поля у всех вариантов.
Реализации перечисляют в том же файле или в списке
permits; снаружи разрешённого списка новую
реализацию добавить нельзя, как у sealed class:
sealed interface PostView permits DraftView, LiveView {
}
final class DraftView implements PostView {
private final String title;
DraftView(String title) {
this.title = title;
}
String title() {
return title;
}
}
final class LiveView implements PostView {
private final String title;
LiveView(String title) {
this.title = title;
}
String title() {
return title;
}
}
Создадим DraftView и проверим его тип выражением
instanceof:
PostView view = new DraftView("Intro");
System.out.println(view instanceof DraftView);
Интерфейс удобен, когда варианты уже наследуют другой
тип или когда иерархию хотят держать плоской. Метод
может принимать PostView и различать реализации
через instanceof:
public class Main {
static String code(PostView view) {
if (view instanceof DraftView) {
return "draft";
}
return "live";
}
public static void main(String[] args) {
System.out.println(code(new LiveView()));
}
}
Запечатанный интерфейс можно сочетать с классами и записями в одном файле, если каждый вариант входит в список разрешённых реализаций:
sealed interface PostState permits EmptyState, TitledState {
}
final class EmptyState implements PostState {
}
final class TitledState implements PostState {
private final String title;
TitledState(String title) {
this.title = title;
}
}
Создадим EmptyState и выведем короткое имя его класса:
PostState state = new EmptyState();
System.out.println(state.getClass().getSimpleName());
Объявите sealed interface RoleMarker с
реализациями GuestMarker и AdminMarker.
Сохраните new AdminMarker() в переменную
типа RoleMarker и выведите её класс.
Объявите sealed interface EmployeeInfo:
NamedInfo с полем name,
UnknownInfo без полей.
Создайте new NamedInfo("Bob"),
сохраните в info и выведите имя.