Î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ă.
// 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ă!