Rantai override pada bab virtual dan override dapat berlanjut tanpa batas, karena method hasil override tetap virtual untuk turunan berikutnya. Dalam praktiknya, tim terkadang ingin memastikan satu implementasi tidak lagi diganti oleh generasi turunan mana pun, misalnya karena logika tersebut sudah melewati pengujian menyeluruh. Kata kunci sealed memberikan kontrol tersebut: pada class, sealed menutup pintu pewarisan; pada member, sealed override menghentikan rantai penggantian.

sealed pada Class #

Class yang ditandai sealed tidak dapat diwarisi. Class lain yang mencoba mewarisinya langsung ditolak compiler. Bentuk ini lazim untuk class utilitas yang desainnya tidak menyediakan titik perluasan, sehingga perilaku class tersebut terjamin tetap sama bagi semua pemakai.

sealed override pada Member #

Member yang ditulis sealed override tetap menggantikan versi base class, tetapi penggantian itu adalah yang terakhir: turunan dari class tersebut tidak boleh men-override lagi. Kata sealed pada member selalu berdampingan dengan override, karena maknanya hanya bermakna bagi member yang menggantikan sesuatu.

Contoh: Menghentikan Rantai Override #

csharp
public class Kendaraan
{
    public virtual void Deskripsikan()
    {
        Console.WriteLine("Ini sebuah kendaraan.");
    }
}

public class Truk : Kendaraan
{
    public sealed override void Deskripsikan()
    {
        Console.WriteLine("Truk pengangkut barang bermuatan besar.");
    }
}

public class TrukPickup : Truk
{
    // Tidak men-override lagi; versi Deskripsikan() milik Truk tetap terpakai.
}

Truk truk = new Truk();
truk.Deskripsikan();

TrukPickup pickup = new TrukPickup();
pickup.Deskripsikan();

Output yang Dihasilkan:

text
Truk pengangkut barang bermuatan besar.
Truk pengangkut barang bermuatan besar.

Mari kita bedah baris demi baris:

  1. public virtual void Deskripsikan(): Base class menyediakan versi dasar yang boleh diganti, sama seperti bab sebelumnya.
  2. public sealed override void Deskripsikan(): Truk menggantikan versi Kendaraan, dan kata sealed menyatakan bahwa tidak ada turunan Truk yang boleh mengganti lagi.
  3. class TrukPickup : Truk: Turunan Truk boleh ada, karena yang ditutup hanyalah member Deskripsikan(), bukan seluruh class.
  4. pickup.Deskripsikan(): TrukPickup tidak punya versi sendiri, sehingga object menjalankan versi terakhir yang sah, yaitu versi Truk; dua baris output identik membuktikan hal itu.

Sebagai pembanding, class yang ditandai sealed tetap dapat dipakai seperti biasa:

csharp
public sealed class BukuKendaraan
{
    public string NomorPolisi;
}

BukuKendaraan buku = new BukuKendaraan();
buku.NomorPolisi = "B 1234 XYZ";
Console.WriteLine($"Buku kendaraan: {buku.NomorPolisi}");

Output yang Dihasilkan:

text
Buku kendaraan: B 1234 XYZ
text
error CS0509: 'BukuServis': cannot derive from sealed type 'BukuKendaraan'

Sedangkan men-override member yang sudah sealed menghasilkan:

text
error CS0239: 'Perkutut.Bersuara()': cannot override inherited member 'Burung.Bersuara()' because it is sealed

Dengan sealed, kita memiliki tombol penuh atas rantai inheritance: buka untuk perluasan, tutup untuk bagian yang dianggap final. Bab berikutnya beralih ke interface implementation, jalur berbagi kontrak yang tidak terikat pada satu rantai class.