Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Sealed Classes и Interfaces в Java
Sealed — это модификатор доступа, введённый в Java 17, который ограничивает, какие классы или интерфейсы могут наследоваться от объявленного класса или интерфейса. Это даёт больше контроля над иерархией типов.
Назначение Sealed
Seal (запечатать) класс означает:
- Явно указать, какие классы могут наследоваться
- Запретить неконтролируемое расширение иерархии
- Улучшить безопасность типов и облегчить рефакторинг
Синтаксис
// Основной класс запечатан
public sealed class Animal permits Dog, Cat, Bird {
public void makeSound() {}
}
// Эти классы могут наследоваться от Animal
public final class Dog extends Animal {
@Override
public void makeSound() {
System.out.println("Woof!");
}
}
public final class Cat extends Animal {
@Override
public void makeSound() {
System.out.println("Meow!");
}
}
public final class Bird extends Animal {
@Override
public void makeSound() {
System.out.println("Chirp!");
}
}
// Эти классы НЕ могут наследоваться
// public class Elephant extends Animal {} // Ошибка компиляции
Уровни запечатывания
У подклассов sealed класса есть три варианта:
1. Final — полностью запечатан
public final class Dog extends Animal {
// Больше никто не может наследоваться от Dog
}
2. Sealed — частично запечатан
public sealed class Mammal extends Animal permits Wolf, Husky {
// Только Wolf и Husky могут наследоваться
}
public final class Wolf extends Mammal {}
public final class Husky extends Mammal {}
3. Non-sealed — открыт для наследования
public non-sealed class Dog extends Animal {
// Кто угодно может наследоваться от Dog
// Восстанавливает обычное наследование
}
public class Poodle extends Dog {} // OK
public class Labrador extends Dog {} // OK
Практический пример: Shape иерархия
// Базовый sealed класс
public sealed class Shape permits Circle, Rectangle, Triangle {
abstract double getArea();
}
// Простые формы
public final class Circle extends Shape {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
double getArea() {
return Math.PI * radius * radius;
}
}
public final class Rectangle extends Shape {
private double width, height;
public Rectangle(double width, double height) {
this.width = width;
this.height = height;
}
@Override
double getArea() {
return width * height;
}
}
Sealed интерфейсы
Так же работает и для интерфейсов (Java 17+):
public sealed interface Shape permits Circle, Rectangle {
double getArea();
}
public final class Circle implements Shape {
private double radius;
@Override
public double getArea() {
return Math.PI * radius * radius;
}
}
Pattern Matching с Sealed Classes
Sealed классы отлично работают с pattern matching (Java 16+):
public static double calculateArea(Shape shape) {
// Компилятор знает все возможные типы
return switch (shape) {
case Circle c -> Math.PI * c.getRadius() * c.getRadius();
case Rectangle r -> r.getWidth() * r.getHeight();
case Triangle t -> calculateTriangleArea(t);
}; // No default needed!
}
Преимущества Sealed
- Безопасность типов — компилятор знает все возможные подклассы
- Облегченный рефакторинг — изменения легче анализировать
- Лучший pattern matching — не нужен default случай
- Явность намерений — показываешь, какое наследование допускается
- Производительность — JVM может делать лучше оптимизации
Когда использовать Sealed
Используй, когда:
- Есть ограниченный набор подклассов
- Хочешь контролировать иерархию типов
- Нужны хорошие pattern matching
- Разработана иерархия классов для варианта (ADT)
Не используй, когда:
- Это library code для внешних разработчиков
- Ещё не ясна полная иерархия
- Нужна гибкость в расширении
Совместимость
Sealed — это часть Java 17+ (LTS версия). Для более ранних версий нужен флаг --enable-preview.
Заключение
Sealed классы и интерфейсы — мощный инструмент для создания безопасных, контролируемых иерархий типов. Они особенно полезны при работе с pattern matching и явном определении возможных подтипов.