Варианты sealed-типа через records в Java
Подтип запечатанного класса или интерфейса часто объявляют
как record, если у варианта есть только набор
полей: для записи автоматически создаются конструктор,
equals, hashCode и toString,
а вариант остаётся частью запечатанной иерархии:
sealed class Post permits DraftPost, PublishedPost, ArchivedPost {
}
record DraftPost(String title) extends Post {
}
record PublishedPost(String title, int views) extends Post {
}
final class ArchivedPost extends Post {
}
Создадим две одинаковые записи и сравним их методом equals:
Post a = new PublishedPost("News", 10);
Post b = new PublishedPost("News", 10);
System.out.println(a.equals(b));
У записи внутри sealed-иерархии можно получить копию
с изменённым полем через метод with, не описывая
его вручную:
PublishedPost post = new PublishedPost("Intro", 1);
PublishedPost updated = post.withViews(5);
System.out.println(updated.views());
В одной иерархии сочетают record для вариантов
с данными и обычный final класс для одиночных
состояний. Разбор в switch остаётся исчерпывающим,
если перечислены все объявленные подтипы:
sealed interface PostState permits Empty, WithTitle {
}
final class Empty implements PostState {
}
record WithTitle(String title) implements PostState {
}
Разберем состояние записи в switch и выведем короткую подпись:
static String show(PostState state) {
return switch (state) {
case Empty e -> "empty";
case WithTitle t -> t.title();
};
}
System.out.println(show(new WithTitle("Hello")));
Объявите sealed class Employee permits NamedEmployee, LeadEmployee:
NamedEmployee как record с полем name,
LeadEmployee как record с полями
name и teamSize.
Создайте два одинаковых NamedEmployee
и выведите true, если они равны.
Объявите sealed interface Role permits GuestRole, UserRole:
GuestRole - пустой final класс,
UserRole - record с полем login.
Дано:
Role role = new UserRole("ann");
В switch выведите "guest" или логин пользователя.