Sealed classes (clases selladas) son una mejora al lenguaje incluido con la versión LTS 17 (incluidas desde la versión 16) de Java. Las clases o interfaces selladas nos permiten restringir que otras clases e interfaces puede extender de ellas.
Nota: Las clases sealed no tiene como objetivo ser un reemplazo a la palabra reservada final
El objetivo de las clases o interfaces sealed
se proporcionar una forma de permitir que una clases sea ampliamente accessible pero a la vez no ampliamente extensible. Estas pueden ser extendidas o implementadas solamente por aquellas clases e interfaces que son explícitamente permitidas.
¿Cómo se usa ?
Una clase o interface es sealed (sellada) aplicando el modificador sealed
a su declaración, luego de cualquier extends o implements se debe agregar la cláusula permits
seguida de las clases que permitimos sean extendidas.
public abstract sealed class Shape permits Circle, Rectangle, Square, WeirdShape { ... }
Luego en nuestras implementaciones debemos de extender la clase sellada.
public final class Circle extends Shape { ... } public final class Rectangule extends Shape { ... } public final class Square extends Shape { ... } public final class WeirdShape extends Shape { ... }
Sub-classes permitidas y sus reglas
Cada subclase permita debe usar un modificador para describir como propagar el sellado iniciado por su super-clase:
- Una sub-clase permitida puede aplicar el modificar
final
para evitar extenderse más. - Una sub-clase permitida puede aplicar el modificador
sealed
seguido de la cláusulapermits
para extender a otras sub-clases en su jerarquía. - Una sub-clase permitida puede aplicar el modificar
non-sealed
de manera que revierte en su propia jerarquía el “sellado” de la clase super clase, y abriendo la extensión a otros clases desconocidas por la super clase.
Veamos unos ejemplos:
public abstract sealed class Shape permits Circle, Rectangle, Square, WeirdShape { ... } public final class Circle extends Shape { ... } public sealed class Rectangle extends Shape permits TransparentRectangle, FilledRectangle { ... } public final class TransparentRectangle extends Rectangle { ... } public final class FilledRectangle extends Rectangle { ... } public final class Square extends Shape { ... } public non-sealed class WeirdShape extends Shape { ... }
En resumen, al menos uno de los modificadores final
, sealed
o non-sealed
de ser aplicado a las sub-clases permitidas.
Interfaces Sealed (Selladas)
Tal como se ha indicado las interfaces también pueden ser selladas de la misma manera que las clases. Se debe de seguir las mismas reglas que las clases selladas, aplicar el modificador sealed
y seguido la cláusula permits
con la lista de implementaciones permitidas.
public sealed interface Expr permits ConstantExpr, PlusExpr, TimesExpr, NegExpr { ... } public final class ConstantExpr implements Expr { ... } public final class PlusExpr implements Expr { ... } public final class TimesExpr implements Expr { ... } public final class NegExpr implements Expr { ... }
Sellado y clases Record
Las clases record
introducidas en Java 15, son implícitamente final
por lo cual es consistente con las reglas para las sub-clases permitidas antes mencionadas.
package com.example.expression; public sealed interface Expr permits ConstantExpr, PlusExpr, TimesExpr, NegExpr { ... } public record ConstantExpr(int i) implements Expr { ... } public record PlusExpr(Expr a, Expr b) implements Expr { ... } public record TimesExpr(Expr a, Expr b) implements Expr { ... } public record NegExpr(Expr e) implements Expr { ... }
Conclusiones
Definitivamente las clases e interfaces sealed son una gran inclusión al lenguaje Java, permitiendo cubrir algunos limitaciones en el lenguaje para los creadores de APIs y librerías, donde en algunos casos se desea restringir la extensibilidad de nuestras clases sin limitar su accesibilidad.
Esta nueva característica abre las puertas para incorporar muchas otras futuras características al lenguaje, como por ejemplo el switch
pattern matching
que está siendo trabajado en JEP 406