Clase Sigilate (Sealed Classes) și Tipuri Algebrice în Java: sealed, non-sealed și permits în Java

Ghid complet pentru Sealed Classes și Interfaces în Java: modelarea tipurilor de date algebrice (Algebraic Data Types), controlul moștenirii cu sealed, permits și non-sealed, și verificarea exhaustivă la compilare.

Sintaxă
public sealed interface PaymentMethod permits CreditCard, BankTransfer, Crypto

În programarea orientată pe obiecte clasică, moștenirea era o sabie cu două tăișuri: o clasă publică putea fi extinsă de orice altă clasă dintr-un pachet extern, făcând imposibilă garantarea că toate subclasele posibile sunt cunoscute în momentul proiectării sistemului.

Clasele Sigilate (Sealed Classes & Interfaces) oferă dezvoltatorului control total asupra moștenirii: o clasă sau interfață marcată cu sealed declară explicit prin clauza permits lista exhaustivă de clase autorizate să o extindă.

Modelarea unui Sistem de Plăți ca Tip Algebric de Date
// 1. Declararea interfeței sigilate:
public sealed interface MetodaPlata 
    permits CardBancar, TransferBancar, Criptomoneda {
    
    double calculeazaComision(double suma);
}

// 2. Fiecare subclasă permisă trebuie să declare explicit cum gestionează moștenirea mai departe:
// Varianta A: 'final' -> ierarhia se oprește complet aici (nu mai poate fi extinsă niciodată)
public final class CardBancar implements MetodaPlata {
    private final String numarCard;
    public CardBancar(String numarCard) { this.numarCard = numarCard; }
    
    @Override
    public double calculeazaComision(double suma) { return suma * 0.015; }
}

// Varianta B: 'sealed' -> continuă să restricționeze propriile subclase permise
public sealed class TransferBancar implements MetodaPlata permits TransferInstant, TransferStandard {
    @Override
    public double calculeazaComision(double suma) { return 5.0; }
}
public final class TransferInstant extends TransferBancar {}
public final class TransferStandard extends TransferBancar {}

// Varianta C: 'non-sealed' -> redeschide moștenirea liberă pentru clienți terți
public non-sealed class Criptomoneda implements MetodaPlata {
    @Override
    public double calculeazaComision(double suma) { return 0.001; }
}

Verificarea Exhaustivă în Expresii switch

Combinate cu switch, clasele sigilate aduc suportul nativ pentru Algebraic Data Types (Sum Types): compilatorul știe că nu pot exista alte variante în afara celor permise și nu vă va forța să scrieți o clauză de protecție default aruncând excepții inutile:

double comision = switch (metoda) {
    case CardBancar c -> c.calculeazaComision(suma);
    case TransferBancar t -> t.calculeazaComision(suma);
    case Criptomoneda crypto -> crypto.calculeazaComision(suma);
}; // Compilare garantată fără erori de ramuri lipsă!