Ответ
Ключевым нововведением для моделирования предметной области стали sealed classes (запечатанные классы), официально добавленные в Java 17. Они позволяют явно ограничивать иерархию наследования.
Проблема до Java 17:
Нельзя было ограничить, какие классы могут расширять базовый класс или интерфейс, что усложняло безопасную работу с типами (например, требовались длинные цепочки instanceof).
Решение с sealed классами:
// Базовый запечатанный класс. Ключевое слово 'permits' указывает допустимых наследников.
public sealed class Shape permits Circle, Rectangle, Triangle {
// Общие свойства и методы для всех фигур
}
// Наследники должны быть явно объявлены как final, sealed или non-sealed.
public final class Circle extends Shape { /* ... */ }
public final class Rectangle extends Shape { /* ... */ }
public final class Triangle extends Shape { /* ... */ }
// Класс 'Square' не сможет унаследовать Shape, так как не указан в permits.
Преимущества и последствия:
- Безопасность типов: Компилятор знает все возможные подтипы, что улучшает анализ и позволяет использовать исчерпывающие выражения
switch(вместе сswitchдля типов, preview в Java 17). - Четкое проектирование: Явно документирует иерархию типов в коде, заменяя антипаттерны.
- Требования к наследникам: Каждый разрешенный наследник должен быть объявлен как:
final– дальнейшее наследование запрещено.sealed– наследование разрешено, но для нового класса также нужен свой списокpermits.non-sealed– класс открыт для неограниченного наследования ("снимает печать").
Ответ 18+ 🔞
А, ну вот, наконец-то, блядь! Сидели, ждали, как манны небесной, а они взяли да и добавили в Java 17 эту штуку — sealed classes, запечатанные классы, ёпта. Суть в чём, блядь? Чтобы можно было наконец-то явно указать, кто имеет право наследоваться, а кто — иди нахуй, в рот меня чих-пых!
Как раньше-то было, до 17-й:
Полный пиздец и бардак, блядь. Объявил ты класс Shape, типа «фигура», и пошло-поехало. Любой распиздяй из соседнего пакета мог взять и наляпать от него наследников: Circle, Square, Trapezoid, а потом ещё и FancyTrapezoidWithSparkles. А ты сиди и в каждом втором методе пиши километровые цепочки if (shape instanceof Circle) ... else if (shape instanceof Square) ..., а потом ещё и default на случай, если вылезет что-то неучтённое. Удивление пиздец, волнение ебать! Компилятор-то нихуя не знает, какие подтипы вообще существуют.
А теперь, с sealed классами, всё по-взрослому: Смотри, как красота, блядь:
// Базовый, запечатанный класс. Ключевое слово 'permits' — это как список гостей на закрытую тусовку.
public sealed class Shape permits Circle, Rectangle, Triangle {
// Тут общие для всех фигур штуки
}
// А вот и гости, блядь. Каждый должен чётко обозначить свой статус.
public final class Circle extends Shape { /* ... */ } // final — всё, приехали, дальше наследоваться нельзя.
public final class Rectangle extends Shape { /* ... */ }
public final class Triangle extends Shape { /* ... */ }
// А вот класс 'Square' сюда уже не пролезет, ёпта. Его нет в permits — значит, ему отказ, в пизду.
И что мы с этого, блядь, имеем?
- Безопасность, мать её, типов! Компилятор теперь в курсе всех возможных наследничков. Это значит, можно писать
switch, который покрывает ВСЕ случаи, и он не будет орать про отсутствиеdefault, потому что варианты-то исчерпаны! (Это вместе сswitchпо типу объекта, который тоже подтянули). - Чёткость в проектировании. Больше не надо гадать, кто от кого произошёл. Всё написано чёрным по белому: вот базовый класс, а вот его законные отпрыски, и точка. Заменяет кучу кривых антипаттернов.
- Правила для наследников — железные. Раз уж попал в список
permits, то обязан объявить себя одним из трёх:final— тупиковая ветвь, дальше ходу нет.sealed— сам такой же запечатанный папа, у которого будет свой собственный списокpermitsдля своих детей.non-sealed— а это, блядь, интересно. Это когда класс говорит: «Ладно, со мной-то можно делать что угодно, наследуйтесь, не стесняйтесь». Снимает с себя печать, так сказать. Но это уже на твоей совести, чувак.
Вот так вот, блядь. Не революция, конечно, но шаг в сторону порядка, а не ебаного хаоса.