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 #
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:
Truk pengangkut barang bermuatan besar.
Truk pengangkut barang bermuatan besar.Mari kita bedah baris demi baris:
public virtual void Deskripsikan(): Base class menyediakan versi dasar yang boleh diganti, sama seperti bab sebelumnya.public sealed override void Deskripsikan():Trukmenggantikan versiKendaraan, dan katasealedmenyatakan bahwa tidak ada turunanTrukyang boleh mengganti lagi.class TrukPickup : Truk: TurunanTrukboleh ada, karena yang ditutup hanyalah memberDeskripsikan(), bukan seluruh class.pickup.Deskripsikan():TrukPickuptidak punya versi sendiri, sehingga object menjalankan versi terakhir yang sah, yaitu versiTruk; dua baris output identik membuktikan hal itu.
Sebagai pembanding, class yang ditandai sealed tetap dapat dipakai seperti biasa:
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:
Buku kendaraan: B 1234 XYZerror CS0509: 'BukuServis': cannot derive from sealed type 'BukuKendaraan'Sedangkan men-override member yang sudah sealed menghasilkan:
error CS0239: 'Perkutut.Bersuara()': cannot override inherited member 'Burung.Bersuara()' because it is sealedDengan 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.