// Hierarki tersegel: hanya tiga tipe ini yang boleh mengimplementasikan Bentuk.
sealed interface Bentuk permits Lingkaran, Persegi, Poligon {
}

// Record otomatis final: menjadi ujung hierarki yang tertutup.
record Lingkaran(double radius) implements Bentuk {
}

record Persegi(double sisi) implements Bentuk {
}

// non-sealed: cabang ini dibuka kembali, boleh diwarisi class apa pun.
non-sealed class Poligon implements Bentuk {
    private final int jumlahSisi;

    public Poligon(int jumlahSisi) {
        this.jumlahSisi = jumlahSisi;
    }

    public int jumlahSisi() {
        return jumlahSisi;
    }
}

// Karena Poligon non-sealed, pewarisan bebas diperbolehkan di cabang ini.
class SegitigaSiku extends Poligon {
    public SegitigaSiku() {
        super(3);
    }
}

public class HierarkiTersegel {
    static String deskripsi(Bentuk bentuk) {
        // Switch pattern matching lengkap TANPA default:
        // compiler memaksa semua permitted terliput.
        return switch (bentuk) {
            case Lingkaran(double radius) -> "lingkaran, radius " + radius;
            case Persegi p -> "persegi, sisi " + p.sisi();
            case Poligon p -> "poligon, " + p.jumlahSisi() + " sisi";
        };
    }

    public static void main(String[] args) {
        Bentuk[] daftar = {
            new Lingkaran(7),
            new Persegi(5),
            new Poligon(6),
            new SegitigaSiku() // subclass Poligon, tertangkap case Poligon
        };

        for (Bentuk b : daftar) {
            System.out.println(deskripsi(b));
        }
    }
}
