Объявление запечатанных типов
Ограничивайте типы, которые можно расширять
«Объявление запечатанных типов» — бесплатный урок Java Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Java Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Java Academy содержит 4 уроков всего.
Что такое запечатанные типы
Запечатанный класс или интерфейс ограничивает набор других типов, которые могут наследоваться от него или реализовывать его. Это позволяет моделировать закрытый набор вариантов, о котором компилятор может рассуждать.
Решаемая проблема
Обычный класс public может быть унаследован кем угодно и где угодно. Иногда требуется ровно три фигуры или два вида оплаты — без неожиданных вариантов. Запечатывание явно выражает это намерение и обеспечивает его соблюдение.
Ключевое слово запечатанного типа
Пометьте тип как sealed и перечислите разрешённые подтипы с помощью permits. Каждый разрешённый подтип должен объявить собственный модификатор наследования.
public class Main {
sealed interface Shape permits Circle, Square {}
record Circle(double radius) implements Shape {}
record Square(double side) implements Shape {}
public static void main(String[] args) {
Shape s = new Circle(2.0);
System.out.println(s);
}
}Модификаторы подтипов
Каждый разрешённый подтип должен быть одним из следующих: final (дальнейшее создание подклассов запрещено), sealed (ограничение продолжается) или non-sealed (наследование снова разрешено без ограничений). Записи неявно являются final.
Конечный подкласс
Пометка подкласса как final закрывает иерархию на этой ветви.
public class Main {
sealed interface Animal permits Dog, Cat {}
static final class Dog implements Animal {
public String toString() { return "Dog"; }
}
static final class Cat implements Animal {
public String toString() { return "Cat"; }
}
public static void main(String[] args) {
Animal a = new Dog();
System.out.println(a);
}
}Незапечатанный подкласс
Подтип non-sealed намеренно снова открывает возможность наследования, позволяя не перечисленным заранее классам наследоваться от него. Используйте его умеренно, когда одна ветвь должна оставаться открытой.
public class Main {
sealed interface Plugin permits CorePlugin, ExternalPlugin {}
static final class CorePlugin implements Plugin {}
static non-sealed class ExternalPlugin implements Plugin {}
static class ThirdParty extends ExternalPlugin {}
public static void main(String[] args) {
Plugin p = new ThirdParty();
System.out.println(p.getClass().getSimpleName());
}
}Запечатанные классы тоже
Запечатывание не ограничивается интерфейсами. Тип abstract sealed class работает так же и может содержать общее состояние и поведение.
public class Main {
sealed static abstract class Expr permits Num, Add {}
static final class Num extends Expr {
final int value;
Num(int value) { this.value = value; }
}
static final class Add extends Expr {
final Expr left, right;
Add(Expr left, Expr right) { this.left = left; this.right = right; }
}
public static void main(String[] args) {
Expr e = new Add(new Num(1), new Num(2));
System.out.println(e.getClass().getSimpleName());
}
}Один модуль или пакет
Разрешённые подтипы должны находиться в том же модуле, что и запечатанный тип, или в том же пакете, если код не разбит на модули. Это позволяет сохранить закрытый набор вместе и проверить его целостность.
Контроль компилятора
Если класс пытается унаследоваться от запечатанного типа, но не указан в permits, код не компилируется. Закрытый набор гарантируется во время компиляции.
Зачем это нужно
Поскольку компилятор знает каждый подтип, он может проверить, что оператор выбора `switch` для запечатанного типа обрабатывает все варианты. Это основа полного сопоставления с образцами, которое рассматривается в следующем курсе.
Полная иерархия
Ниже приведена небольшая закрытая иерархия, используемая для моделирования значений.
public class Main {
sealed interface Json permits JsonNull, JsonNumber, JsonString {}
record JsonNull() implements Json {}
record JsonNumber(double value) implements Json {}
record JsonString(String value) implements Json {}
public static void main(String[] args) {
Json[] values = { new JsonNull(), new JsonNumber(3.5), new JsonString("hi") };
for (Json j : values) {
System.out.println(j);
}
}
}Быстрая проверка
Проверьте своё понимание объявлений запечатанных типов.
Итоги
Вы научились объявлять запечатанные типы.
sealedограничивает круг тех, кто может наследоваться от типа или реализовывать его.- Предложение
permitsперечисляет разрешённые подтипы. - Каждый подтип должен быть
final,sealedилиnon-sealed. - Подтипы находятся в том же модуле или пакете, а компилятор проверяет соблюдение этого правила.
Часто задаваемые вопросы
Урок «Объявление запечатанных типов» бесплатный?
Да — полный текст урока «Объявление запечатанных типов» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Java Academy, подпишись на CoddyKit PRO. Курс Java Academy содержит 4 уроков всего.
Чему я научусь в уроке «Объявление запечатанных типов»?
Ограничивайте типы, которые можно расширять Ты практикуешь Java Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Java Academy?
Предыдущий опыт не требуется. Java Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.
Сколько времени занимает урок «Объявление запечатанных типов»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Java Academy?
Да. Каждый урок Java Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Объявление запечатанных типов
- Условие permits
- Запечатанные типы с record
- Полный switch по запечатанному типу